mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-13 11:38:19 +00:00
9a89e58a16
See also Jupeyy's explanation in https://github.com/ddnet/ddnet/issues/4294 for why we want to ignore this: > sadly components have no OnDestruct on anything like that > so aslong it doesn't actually leak it's just non destructed memory So it's something we allocate once for the entire client lifetime from my understanding. ================================================================= ==421461==ERROR: LeakSanitizer: detected memory leaks Direct leak of 411760 byte(s) in 10 object(s) allocated from: #0 0x55eaf0c08a29 in malloc (/media/ddnet/integration_test/DDNet+0x736a29) #1 0x55eaf0de9f72 in CCommandProcessorFragment_OpenGL2::Cmd_CreateBufferObject(CCommandBuffer::SCommand_CreateBufferObject const*) /media/ddnet/src/engine/client/backend/opengl/backend_opengl.cpp:1898:25 #2 0x55eaf0dd82f5 in CCommandProcessorFragment_OpenGL::RunCommand(CCommandBuffer::SCommand const*) /media/ddnet/src/engine/client/backend/opengl/backend_opengl.cpp #3 0x55eaf0f73229 in CCommandProcessor_SDL_GL::RunBuffer(CCommandBuffer*) /media/ddnet/src/engine/client/backend_sdl.cpp:246:20 #4 0x55eaf0f70568 in CGraphicsBackend_Threaded::ThreadFunc(void*) /media/ddnet/src/engine/client/backend_sdl.cpp:75:25 #5 0x55eaf0d679d7 in thread_run(void*) /media/ddnet/src/base/system.cpp:686:2 #6 0x7f08b788c54c (/usr/lib/libc.so.6+0x8c54c) SUMMARY: AddressSanitizer: 411760 byte(s) leaked in 10 allocation(s).
319 lines
6.6 KiB
Bash
Executable file
319 lines
6.6 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
if [ ! -f scripts/integration_test.sh ] || [ ! -f CMakeLists.txt ]
|
|
then
|
|
echo "Error: make sure your are in the root of the repo"
|
|
exit 1
|
|
fi
|
|
|
|
arg_build_dir="build"
|
|
arg_end_args=0
|
|
arg_verbose=0
|
|
arg_valgrind_memcheck=0
|
|
|
|
for arg in "$@"
|
|
do
|
|
if [[ "${arg::1}" == "-" ]] && [[ "$arg_end_args" == "0" ]]
|
|
then
|
|
if [ "$arg" == "-h" ] || [ "$arg" == "--help" ]
|
|
then
|
|
echo "usage: $(basename "$0") [OPTION..] [build dir]"
|
|
echo "description:"
|
|
echo " Runs a simple integration test of the client and server"
|
|
echo " binaries from the given build dir"
|
|
echo "options:"
|
|
echo " --help|-h show this help"
|
|
echo " --verbose|-v verbose output"
|
|
elif [ "$arg" == "-v" ] || [ "$arg" == "--verbose" ]
|
|
then
|
|
arg_verbose=1
|
|
elif [ "$arg" == "--valgrind-memcheck" ]
|
|
then
|
|
arg_valgrind_memcheck=1
|
|
elif [ "$arg" == "--" ]
|
|
then
|
|
arg_end_args=1
|
|
else
|
|
echo "Error: unknown arg '$arg'"
|
|
fi
|
|
else
|
|
arg_build_dir="$arg"
|
|
fi
|
|
done
|
|
|
|
if [ ! -d "$arg_build_dir" ]
|
|
then
|
|
echo "Error: build directory '$arg_build_dir' not found"
|
|
exit 1
|
|
fi
|
|
if [ ! -f "$arg_build_dir"/DDNet ]
|
|
then
|
|
echo "Error: client binary not found '$arg_build_dir/DDNet' not found"
|
|
exit 1
|
|
fi
|
|
if [ ! -f "$arg_build_dir"/DDNet-Server ]
|
|
then
|
|
echo "Error: server binary not found '$arg_build_dir/DDNet-Server' not found"
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p integration_test
|
|
cp "$arg_build_dir"/DDNet* integration_test
|
|
|
|
cd integration_test || exit 1
|
|
|
|
got_killed=0
|
|
|
|
function kill_all() {
|
|
# needed to fix hang fifo with additional ctrl+c
|
|
if [ "$got_killed" == "1" ]
|
|
then
|
|
exit
|
|
fi
|
|
got_killed=1
|
|
|
|
if [ "$arg_verbose" == "1" ]
|
|
then
|
|
echo "[*] shutting down test clients and server ..."
|
|
fi
|
|
|
|
sleep 1
|
|
echo "shutdown" > server.fifo
|
|
echo "quit" > client1.fifo
|
|
echo "quit" > client2.fifo
|
|
}
|
|
|
|
function cleanup() {
|
|
kill_all
|
|
}
|
|
|
|
trap cleanup EXIT
|
|
|
|
{
|
|
echo $'add_path $CURRENTDIR'
|
|
echo $'add_path $USERDIR'
|
|
echo $'add_path $DATADIR'
|
|
echo $'add_path ../data'
|
|
} > storage.cfg
|
|
|
|
function fail()
|
|
{
|
|
sleep 1
|
|
tail -n2 "$1".log > fail_"$1".txt
|
|
echo "$1 exited with code $2" >> fail_"$1".txt
|
|
echo "[-] $1 exited with code $2"
|
|
}
|
|
|
|
if test -n "$(find . -maxdepth 1 -name '*.fifo' -print -quit)"
|
|
then
|
|
rm ./*.fifo
|
|
fi
|
|
if test -n "$(find . -maxdepth 1 -name 'SAN.*' -print -quit)"
|
|
then
|
|
rm SAN.*
|
|
fi
|
|
if test -n "$(find . -maxdepth 1 -name 'fail_*' -print -quit)"
|
|
then
|
|
rm fail_*
|
|
fi
|
|
if [ -f ddnet-server.sqlite ]
|
|
then
|
|
rm ddnet-server.sqlite
|
|
fi
|
|
|
|
# TODO: check for open ports instead
|
|
port=17822
|
|
|
|
cp ../ubsan.supp ../lsan.supp ../memcheck.supp .
|
|
|
|
if [[ $OSTYPE == 'darwin'* ]]; then
|
|
DETECT_LEAKS=0
|
|
else
|
|
DETECT_LEAKS=1
|
|
fi
|
|
|
|
export UBSAN_OPTIONS=suppressions=./ubsan.supp:log_path=./SAN:print_stacktrace=1:halt_on_errors=0
|
|
export ASAN_OPTIONS=log_path=./SAN:print_stacktrace=1:check_initialization_order=1:detect_leaks=$DETECT_LEAKS:halt_on_errors=0
|
|
export LSAN_OPTIONS=suppressions=./lsan.supp
|
|
|
|
function print_results() {
|
|
if [ "$arg_valgrind_memcheck" == "1" ]; then
|
|
if grep "ERROR SUMMARY" server.log client1.log client2.log | grep -q -v "ERROR SUMMARY: 0"; then
|
|
grep "^==" server.log client1.log client2.log
|
|
return 1
|
|
fi
|
|
else
|
|
if test -n "$(find . -maxdepth 1 -name 'SAN.*' -print -quit)"
|
|
then
|
|
cat SAN.*
|
|
return 1
|
|
fi
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
if [ "$arg_valgrind_memcheck" == "1" ]; then
|
|
tool="valgrind --tool=memcheck --gen-suppressions=all --suppressions=memcheck.supp --track-origins=yes"
|
|
client_args="cl_menu_map \"\";"
|
|
else
|
|
tool=""
|
|
client_args=""
|
|
fi
|
|
|
|
$tool ./DDNet-Server \
|
|
"sv_input_fifo server.fifo;
|
|
sv_rcon_password rcon;
|
|
sv_map coverage;
|
|
sv_sqlite_file ddnet-server.sqlite;
|
|
sv_port $port" &> server.log || fail server "$?" &
|
|
|
|
$tool ./DDNet \
|
|
"cl_input_fifo client1.fifo;
|
|
player_name client1;
|
|
cl_download_skins 0;
|
|
gfx_fullscreen 0;
|
|
$client_args
|
|
connect localhost:$port" &> client1.log || fail client1 "$?" &
|
|
|
|
if [ "$arg_valgrind_memcheck" == "1" ]; then
|
|
sleep 10
|
|
else
|
|
sleep 1
|
|
fi
|
|
|
|
$tool ./DDNet \
|
|
"cl_input_fifo client2.fifo;
|
|
player_name client2;
|
|
cl_download_skins 0;
|
|
gfx_fullscreen 0;
|
|
$client_args
|
|
connect localhost:$port" &> client2.log || fail client2 "$?" &
|
|
|
|
fails=0
|
|
if [ "$arg_valgrind_memcheck" == "1" ]; then
|
|
tries=120
|
|
else
|
|
tries=2
|
|
fi
|
|
# give the client time to launch and create the fifo file
|
|
# but assume after X secs that the client crashed before
|
|
# being able to create the file
|
|
while [[ ! -p client1.fifo || ! -p client2.fifo ]]
|
|
do
|
|
fails="$((fails+1))"
|
|
if [ "$arg_verbose" == "1" ]
|
|
then
|
|
echo "[!] client fifos not found (attempts $fails/$tries)"
|
|
fi
|
|
if [ "$fails" -gt "$tries" ]
|
|
then
|
|
print_results
|
|
echo "[-] Error: client possibly crashed on launch"
|
|
exit 1
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
if [ "$arg_valgrind_memcheck" == "1" ]; then
|
|
sleep 20
|
|
else
|
|
sleep 2
|
|
fi
|
|
|
|
echo "[*] test chat and chat commands"
|
|
echo "say hello world" > client1.fifo
|
|
echo "rcon_auth rcon" > client1.fifo
|
|
sleep 1
|
|
tr -d '\n' > client1.fifo << EOF
|
|
say "/mc
|
|
;top5
|
|
;rank
|
|
;team 512
|
|
;emote happy -999
|
|
;pause
|
|
;points
|
|
;mapinfo
|
|
;list
|
|
;whisper client2 hi
|
|
;kill
|
|
;settings cheats
|
|
;timeout 123
|
|
;timer broadcast
|
|
;cmdlist
|
|
;saytime"
|
|
EOF
|
|
sleep 1
|
|
echo "[*] test rcon commands"
|
|
tr -d '\n' > client1.fifo << EOF
|
|
rcon say hello from admin;
|
|
rcon broadcast test;
|
|
rcon status;
|
|
rcon echo test;
|
|
muteid 1 900 spam;
|
|
unban_all;
|
|
EOF
|
|
sleep 1
|
|
|
|
|
|
# TODO: remove the first grep after https://github.com/ddnet/ddnet/pull/5036 is merged
|
|
if ! grep -qE '^\[[0-9]{4}-[0-9]{2}-[0-9]{2} ([0-9]{2}:){2}[0-9]{2}\]\[chat\]: 0:-2:client1: hello world$' server.log && \
|
|
! grep -qE '^[0-9]{4}-[0-9]{2}-[0-9]{2} ([0-9]{2}:){2}[0-9]{2} D chat: 0:-2:client1: hello world$' server.log
|
|
then
|
|
touch fail_chat.txt
|
|
echo "[-] Error: chat message not found in server log"
|
|
fi
|
|
if ! grep -q 'cmdlist' client1.log || \
|
|
! grep -q 'pause' client1.log || \
|
|
! grep -q 'rank' client1.log || \
|
|
! grep -q 'points' client1.log
|
|
then
|
|
touch fail_chatcommand.txt
|
|
echo "[-] Error: did not find output of /cmdlist command"
|
|
fi
|
|
|
|
if ! grep -q "hello from admin" server.log
|
|
then
|
|
touch fail_rcon.txt
|
|
echo "[-] Error: admin message not found in server log"
|
|
fi
|
|
|
|
kill_all
|
|
wait
|
|
|
|
sleep 1
|
|
|
|
ranks="$(sqlite3 ddnet-server.sqlite < <(echo "select * from record_race;"))"
|
|
num_ranks="$(echo "$ranks" | wc -l | xargs)"
|
|
if [ "$ranks" == "" ]
|
|
then
|
|
touch fail_ranks.txt
|
|
echo "[-] Error: no ranks found in database"
|
|
elif [ "$num_ranks" != "1" ]
|
|
then
|
|
touch fail_ranks.txt
|
|
echo "[-] Error: expected 1 rank got $num_ranks"
|
|
elif ! echo "$ranks" | grep -q client1
|
|
then
|
|
touch fail_ranks.txt
|
|
echo "[-] Error: expected a rank from client1 instead got:"
|
|
echo " $ranks"
|
|
fi
|
|
|
|
if test -n "$(find . -maxdepth 1 -name 'fail_*' -print -quit)"
|
|
then
|
|
if [ "$arg_verbose" == "1" ]
|
|
then
|
|
for fail in fail_*
|
|
do
|
|
cat "$fail"
|
|
done
|
|
fi
|
|
print_results
|
|
echo "[-] Test failed. See errors above."
|
|
exit 1
|
|
else
|
|
echo "[*] all tests passed"
|
|
fi
|
|
|
|
print_results || exit 1
|