1#!/usr/bin/env bash 2# 3# Copyright (C) 2019-2021 Red Hat, Inc. 4# This file is part of elfutils. 5# 6# This file is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 3 of the License, or 9# (at your option) any later version. 10# 11# elfutils is distributed in the hope that it will be useful, but 12# WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program. If not, see <http://www.gnu.org/licenses/>. 18 19. $srcdir/test-subr.sh # includes set -e 20 21type curl 2>/dev/null || (echo "need curl"; exit 77) 22type rpm2cpio 2>/dev/null || (echo "need rpm2cpio"; exit 77) 23type cpio 2>/dev/null || (echo "need cpio"; exit 77) 24type bzcat 2>/dev/null || (echo "need bzcat"; exit 77) 25bsdtar --version | grep -q zstd && zstd=true || zstd=false 26echo "zstd=$zstd bsdtar=`bsdtar --version`" 27 28# for test case debugging, uncomment: 29#set -x 30VERBOSE=-vvv 31 32DB=${PWD}/.debuginfod_tmp.sqlite 33tempfiles $DB 34export DEBUGINFOD_CACHE_PATH=${PWD}/.client_cache 35 36PID1=0 37PID2=0 38PID3=0 39 40cleanup() 41{ 42 if [ $PID1 -ne 0 ]; then kill $PID1; wait $PID1; fi 43 if [ $PID2 -ne 0 ]; then kill $PID2; wait $PID2; fi 44 if [ $PID3 -ne 0 ]; then kill $PID3; wait $PID3; fi 45 46 rm -rf F R D L Z ${PWD}/foobar ${PWD}/mocktree ${PWD}/.client_cache* ${PWD}/tmp* 47 exit_cleanup 48} 49 50# clean up trash if we were aborted early 51trap cleanup 0 1 2 3 5 9 15 52 53errfiles_list= 54err() { 55 for ports in $PORT1 $PORT2 56 do 57 echo $port metrics 58 curl -s http://127.0.0.1:$port/metrics 59 echo 60 done 61 for x in $errfiles_list 62 do 63 echo "$x" 64 cat $x 65 echo 66 done 67} 68trap err ERR 69 70errfiles() { 71 errfiles_list="$errfiles_list $*" 72} 73 74 75 76# find an unused port number 77while true; do 78 PORT1=`expr '(' $RANDOM % 1000 ')' + 9000` 79 ss -atn | fgrep ":$PORT1" || break 80done 81 82# We want to run debuginfod in the background. We also want to start 83# it with the same check/installcheck-sensitive LD_LIBRARY_PATH stuff 84# that the testrun alias sets. But: we if we just use 85# testrun .../debuginfod 86# it runs in a subshell, with different pid, so not helpful. 87# 88# So we gather the LD_LIBRARY_PATH with this cunning trick: 89ldpath=`testrun sh -c 'echo $LD_LIBRARY_PATH'` 90 91mkdir F R L D Z 92# not tempfiles F R L D Z - they are directories which we clean up manually 93ln -s ${abs_builddir}/dwfllines L/foo # any program not used elsewhere in this test 94 95wait_ready() 96{ 97 port=$1; 98 what=$2; 99 value=$3; 100 timeout=20; 101 102 echo "Wait $timeout seconds on $port for metric $what to change to $value" 103 while [ $timeout -gt 0 ]; do 104 mvalue="$(curl -s http://127.0.0.1:$port/metrics \ 105 | grep "$what" | awk '{print $NF}')" 106 if [ -z "$mvalue" ]; then mvalue=0; fi 107 echo "metric $what: $mvalue" 108 if [ "$mvalue" -eq "$value" ]; then 109 break; 110 fi 111 sleep 0.5; 112 ((timeout--)); 113 done; 114 115 if [ $timeout -eq 0 ]; then 116 echo "metric $what never changed to $value on port $port" 117 exit 1; 118 fi 119} 120 121# create a bogus .rpm file to evoke a metric-visible error 122# Use a cyclic symlink instead of chmod 000 to make sure even root 123# would see an error (running the testsuite under root is NOT encouraged). 124ln -s R/nothing.rpm R/nothing.rpm 125 126env LD_LIBRARY_PATH=$ldpath DEBUGINFOD_URLS= ${abs_builddir}/../debuginfod/debuginfod $VERBOSE -F -R -d $DB -p $PORT1 -t0 -g0 --fdcache-fds 1 --fdcache-mbs 2 --fdcache-mintmp 0 -Z .tar.xz -Z .tar.bz2=bzcat -v R F Z L > vlog$PORT1 2>&1 & 127PID1=$! 128tempfiles vlog$PORT1 129errfiles vlog$PORT1 130# Server must become ready 131wait_ready $PORT1 'ready' 1 132export DEBUGINFOD_URLS=http://127.0.0.1:$PORT1/ # or without trailing / 133 134# Be patient when run on a busy machine things might take a bit. 135export DEBUGINFOD_TIMEOUT=10 136 137# Check thread comm names 138ps -q $PID1 -e -L -o '%p %c %a' | grep groom 139ps -q $PID1 -e -L -o '%p %c %a' | grep scan 140ps -q $PID1 -e -L -o '%p %c %a' | grep traverse 141 142# We use -t0 and -g0 here to turn off time-based scanning & grooming. 143# For testing purposes, we just sic SIGUSR1 / SIGUSR2 at the process. 144 145######################################################################## 146 147# Compile a simple program, strip its debuginfo and save the build-id. 148# Also move the debuginfo into another directory so that elfutils 149# cannot find it without debuginfod. 150echo "int main() { return 0; }" > ${PWD}/prog.c 151tempfiles prog.c 152# Create a subdirectory to confound source path names 153mkdir foobar 154gcc -Wl,--build-id -g -o prog ${PWD}/foobar///./../prog.c 155testrun ${abs_top_builddir}/src/strip -g -f prog.debug ${PWD}/prog 156BUILDID=`env LD_LIBRARY_PATH=$ldpath ${abs_builddir}/../src/readelf \ 157 -a prog | grep 'Build ID' | cut -d ' ' -f 7` 158 159wait_ready $PORT1 'thread_work_total{role="traverse"}' 1 160mv prog F 161mv prog.debug F 162kill -USR1 $PID1 163# Wait till both files are in the index. 164wait_ready $PORT1 'thread_work_total{role="traverse"}' 2 165wait_ready $PORT1 'thread_work_pending{role="scan"}' 0 166wait_ready $PORT1 'thread_busy{role="scan"}' 0 167 168######################################################################## 169 170# Test whether elfutils, via the debuginfod client library dlopen hooks, 171# is able to fetch debuginfo from the local debuginfod. 172testrun ${abs_builddir}/debuginfod_build_id_find -e F/prog 1 173 174######################################################################## 175 176# PR25628 177rm -rf $DEBUGINFOD_CACHE_PATH # clean it from previous tests 178 179# The query is designed to fail, while the 000-permission file should be created. 180testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo 01234567 || true 181if [ ! -f $DEBUGINFOD_CACHE_PATH/01234567/debuginfo ]; then 182 echo "could not find cache in $DEBUGINFOD_CACHE_PATH" 183 exit 1 184fi 185 186if [ -r $DEBUGINFOD_CACHE_PATH/01234567/debuginfo ]; then 187 echo "The cache $DEBUGINFOD_CACHE_PATH/01234567/debuginfo is readable" 188 exit 1 189fi 190 191bytecount_before=`curl -s http://127.0.0.1:$PORT1/metrics | grep 'http_responses_transfer_bytes_count{code="404"}'` 192testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo 01234567 || true 193bytecount_after=`curl -s http://127.0.0.1:$PORT1/metrics | grep 'http_responses_transfer_bytes_count{code="404"}'` 194if [ "$bytecount_before" != "$bytecount_after" ]; then 195 echo "http_responses_transfer_bytes_count{code="404"} has changed." 196 exit 1 197fi 198 199# set cache_miss_s to 0 and sleep 1 to make the mtime expire. 200echo 0 > $DEBUGINFOD_CACHE_PATH/cache_miss_s 201sleep 1 202bytecount_before=`curl -s http://127.0.0.1:$PORT1/metrics | grep 'http_responses_transfer_bytes_count{code="404"}'` 203testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo 01234567 || true 204bytecount_after=`curl -s http://127.0.0.1:$PORT1/metrics | grep 'http_responses_transfer_bytes_count{code="404"}'` 205if [ "$bytecount_before" == "$bytecount_after" ]; then 206 echo "http_responses_transfer_bytes_count{code="404"} should be incremented." 207 exit 1 208fi 209######################################################################## 210 211# Test whether debuginfod-find is able to fetch those files. 212rm -rf $DEBUGINFOD_CACHE_PATH # clean it from previous tests 213filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID` 214cmp $filename F/prog.debug 215if [ -w $filename ]; then 216 echo "cache file writable, boo" 217 exit 1 218fi 219 220filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find executable F/prog` 221cmp $filename F/prog 222 223# raw source filename 224filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find source $BUILDID ${PWD}/foobar///./../prog.c` 225cmp $filename ${PWD}/prog.c 226 227# and also the canonicalized one 228filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find source $BUILDID ${PWD}/prog.c` 229cmp $filename ${PWD}/prog.c 230 231 232######################################################################## 233 234# Test whether the cache default locations are correct 235 236mkdir tmphome 237 238# $HOME/.cache should be created. 239testrun env HOME=$PWD/tmphome XDG_CACHE_HOME= DEBUGINFOD_CACHE_PATH= ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID 240if [ ! -f $PWD/tmphome/.cache/debuginfod_client/$BUILDID/debuginfo ]; then 241 echo "could not find cache in $PWD/tmphome/.cache" 242 exit 1 243fi 244 245# $HOME/.cache should be found. 246testrun env HOME=$PWD/tmphome XDG_CACHE_HOME= DEBUGINFOD_CACHE_PATH= ${abs_top_builddir}/debuginfod/debuginfod-find executable $BUILDID 247if [ ! -f $PWD/tmphome/.cache/debuginfod_client/$BUILDID/executable ]; then 248 echo "could not find cache in $PWD/tmphome/.cache" 249 exit 1 250fi 251 252# $XDG_CACHE_HOME should take priority over $HOME.cache. 253testrun env HOME=$PWD/tmphome XDG_CACHE_HOME=$PWD/tmpxdg DEBUGINFOD_CACHE_PATH= ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID 254if [ ! -f $PWD/tmpxdg/debuginfod_client/$BUILDID/debuginfo ]; then 255 echo "could not find cache in $PWD/tmpxdg/" 256 exit 1 257fi 258 259# A cache at the old default location ($HOME/.debuginfod_client_cache) should take 260# priority over $HOME/.cache, $XDG_CACHE_HOME. 261cp -r $DEBUGINFOD_CACHE_PATH tmphome/.debuginfod_client_cache 262 263# Add a file that doesn't exist in $HOME/.cache, $XDG_CACHE_HOME. 264mkdir tmphome/.debuginfod_client_cache/deadbeef 265echo ELF... > tmphome/.debuginfod_client_cache/deadbeef/debuginfo 266filename=`testrun env HOME=$PWD/tmphome XDG_CACHE_HOME=$PWD/tmpxdg DEBUGINFOD_CACHE_PATH= ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo deadbeef` 267cmp $filename tmphome/.debuginfod_client_cache/deadbeef/debuginfo 268 269# $DEBUGINFO_CACHE_PATH should take priority over all else. 270testrun env HOME=$PWD/tmphome XDG_CACHE_HOME=$PWD/tmpxdg DEBUGINFOD_CACHE_PATH=$PWD/tmpcache ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID 271if [ ! -f $PWD/tmpcache/$BUILDID/debuginfo ]; then 272 echo "could not find cache in $PWD/tmpcache/" 273 exit 1 274fi 275 276######################################################################## 277 278# Add artifacts to the search paths and test whether debuginfod finds them while already running. 279 280# Build another, non-stripped binary 281echo "int main() { return 0; }" > ${PWD}/prog2.c 282tempfiles prog2.c 283gcc -Wl,--build-id -g -o prog2 ${PWD}/prog2.c 284BUILDID2=`env LD_LIBRARY_PATH=$ldpath ${abs_builddir}/../src/readelf \ 285 -a prog2 | grep 'Build ID' | cut -d ' ' -f 7` 286 287mv prog2 F 288kill -USR1 $PID1 289# Now there should be 3 files in the index 290wait_ready $PORT1 'thread_work_total{role="traverse"}' 3 291wait_ready $PORT1 'thread_work_pending{role="scan"}' 0 292wait_ready $PORT1 'thread_busy{role="scan"}' 0 293 294# Rerun same tests for the prog2 binary 295filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find -v debuginfo $BUILDID2 2>vlog` 296cmp $filename F/prog2 297cat vlog 298grep -q Progress vlog 299grep -q Downloaded.from vlog 300tempfiles vlog 301filename=`testrun env DEBUGINFOD_PROGRESS=1 ${abs_top_builddir}/debuginfod/debuginfod-find executable $BUILDID2 2>vlog2` 302cmp $filename F/prog2 303cat vlog2 304grep -q 'Downloading.*http' vlog2 305tempfiles vlog2 306filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find source $BUILDID2 ${PWD}/prog2.c` 307cmp $filename ${PWD}/prog2.c 308 309cp -rvp ${abs_srcdir}/debuginfod-rpms R 310if [ "$zstd" = "false" ]; then # nuke the zstd fedora 31 ones 311 rm -vrf R/debuginfod-rpms/fedora31 312fi 313 314cp -rvp ${abs_srcdir}/debuginfod-tars Z 315kill -USR1 $PID1 316# All rpms need to be in the index, except the dummy permission-000 one 317rpms=$(find R -name \*rpm | grep -v nothing | wc -l) 318wait_ready $PORT1 'scanned_files_total{source=".rpm archive"}' $rpms 319txz=$(find Z -name \*tar.xz | wc -l) 320wait_ready $PORT1 'scanned_files_total{source=".tar.xz archive"}' $txz 321tb2=$(find Z -name \*tar.bz2 | wc -l) 322wait_ready $PORT1 'scanned_files_total{source=".tar.bz2 archive"}' $tb2 323 324kill -USR1 $PID1 # two hits of SIGUSR1 may be needed to resolve .debug->dwz->srefs 325# Expect all source files found in the rpms (they are all called hello.c :) 326# We will need to extract all rpms (in their own directory) and could all 327# sources referenced in the .debug files. 328mkdir extracted 329cd extracted 330subdir=0; 331newrpms=$(find ../R -name \*\.rpm | grep -v nothing) 332for i in $newrpms; do 333 subdir=$[$subdir+1]; 334 mkdir $subdir; 335 cd $subdir; 336 ls -lah ../$i 337 rpm2cpio ../$i | cpio -ivd; 338 cd ..; 339done 340sourcefiles=$(find -name \*\\.debug \ 341 | env LD_LIBRARY_PATH=$ldpath xargs \ 342 ${abs_top_builddir}/src/readelf --debug-dump=decodedline \ 343 | grep mtime: | wc --lines) 344cd .. 345rm -rf extracted 346 347wait_ready $PORT1 'found_sourcerefs_total{source=".rpm archive"}' $sourcefiles 348 349# Run a bank of queries against the debuginfod-rpms / debuginfod-debs test cases 350 351archive_test() { 352 __BUILDID=$1 353 __SOURCEPATH=$2 354 __SOURCESHA1=$3 355 356 filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find executable $__BUILDID` 357 buildid=`env LD_LIBRARY_PATH=$ldpath ${abs_builddir}/../src/readelf \ 358 -a $filename | grep 'Build ID' | cut -d ' ' -f 7` 359 test $__BUILDID = $buildid 360 # check that timestamps are plausible - older than the near-present (tmpdir mtime) 361 test $filename -ot `pwd` 362 363 # run again to assure that fdcache is being enjoyed 364 filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find executable $__BUILDID` 365 buildid=`env LD_LIBRARY_PATH=$ldpath ${abs_builddir}/../src/readelf \ 366 -a $filename | grep 'Build ID' | cut -d ' ' -f 7` 367 test $__BUILDID = $buildid 368 test $filename -ot `pwd` 369 370 filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $__BUILDID` 371 buildid=`env LD_LIBRARY_PATH=$ldpath ${abs_builddir}/../src/readelf \ 372 -a $filename | grep 'Build ID' | cut -d ' ' -f 7` 373 test $__BUILDID = $buildid 374 test $filename -ot `pwd` 375 376 if test "x$__SOURCEPATH" != "x"; then 377 filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find source $__BUILDID $__SOURCEPATH` 378 hash=`cat $filename | sha1sum | awk '{print $1}'` 379 test $__SOURCESHA1 = $hash 380 test $filename -ot `pwd` 381 fi 382} 383 384 385# common source file sha1 386SHA=f4a1a8062be998ae93b8f1cd744a398c6de6dbb1 387# fedora31 388if [ $zstd = true ]; then 389 # fedora31 uses zstd compression on rpms, older rpm2cpio/libarchive can't handle it 390 # and we're not using the fancy -Z '.rpm=(rpm2cpio|zstdcat)<' workaround in this testsuite 391 archive_test 420e9e3308971f4b817cc5bf83928b41a6909d88 /usr/src/debug/hello3-1.0-2.x86_64/foobar////./../hello.c $SHA 392 archive_test 87c08d12c78174f1082b7c888b3238219b0eb265 /usr/src/debug/hello3-1.0-2.x86_64///foobar/./..//hello.c $SHA 393fi 394# fedora30 395archive_test c36708a78618d597dee15d0dc989f093ca5f9120 /usr/src/debug/hello2-1.0-2.x86_64/hello.c $SHA 396archive_test 41a236eb667c362a1c4196018cc4581e09722b1b /usr/src/debug/hello2-1.0-2.x86_64/hello.c $SHA 397# rhel7 398archive_test bc1febfd03ca05e030f0d205f7659db29f8a4b30 /usr/src/debug/hello-1.0/hello.c $SHA 399archive_test f0aa15b8aba4f3c28cac3c2a73801fefa644a9f2 /usr/src/debug/hello-1.0/hello.c $SHA 400# rhel6 401archive_test bbbf92ebee5228310e398609c23c2d7d53f6e2f9 /usr/src/debug/hello-1.0/hello.c $SHA 402archive_test d44d42cbd7d915bc938c81333a21e355a6022fb7 /usr/src/debug/hello-1.0/hello.c $SHA 403# arch 404archive_test cee13b2ea505a7f37bd20d271c6bc7e5f8d2dfcb /usr/src/debug/hello.c 7a1334e086b97e5f124003a6cfb3ed792d10cdf4 405 406RPM_BUILDID=d44d42cbd7d915bc938c81333a21e355a6022fb7 # in rhel6/ subdir, for a later test 407 408 409######################################################################## 410 411# Drop some of the artifacts, run a groom cycle; confirm that 412# debuginfod has forgotten them, but remembers others 413 414rm -r R/debuginfod-rpms/rhel6/* 415kill -USR2 $PID1 # groom cycle 416# 1 groom cycle already took place at/soon-after startup, so -USR2 makes 2 417wait_ready $PORT1 'thread_work_total{role="groom"}' 2 418# Expect 4 rpms containing 2 buildids to be deleted by the groom 419wait_ready $PORT1 'groomed_total{decision="stale"}' 4 420 421rm -rf $DEBUGINFOD_CACHE_PATH # clean it from previous tests 422 423# this is one of the buildids from the groom-deleted rpms 424testrun ${abs_top_builddir}/debuginfod/debuginfod-find executable $RPM_BUILDID && false || true 425# but this one was not deleted so should be still around 426testrun ${abs_top_builddir}/debuginfod/debuginfod-find executable $BUILDID2 427 428######################################################################## 429 430# PR26810: Now rename some files in the R directory, then rescan, so 431# there are two copies of the same buildid in the index, one for the 432# no-longer-existing file name, and one under the new name. 433 434# run a groom cycle to force server to drop its fdcache 435kill -USR2 $PID1 # groom cycle 436wait_ready $PORT1 'thread_work_total{role="groom"}' 3 437# move it around a couple of times to make it likely to hit a nonexistent entry during iteration 438mv R/debuginfod-rpms/rhel7 R/debuginfod-rpms/rhel7renamed 439kill -USR1 $PID1 # scan cycle 440wait_ready $PORT1 'thread_work_total{role="traverse"}' 6 441wait_ready $PORT1 'thread_work_pending{role="scan"}' 0 442wait_ready $PORT1 'thread_busy{role="scan"}' 0 443mv R/debuginfod-rpms/rhel7renamed R/debuginfod-rpms/rhel7renamed2 444kill -USR1 $PID1 # scan cycle 445wait_ready $PORT1 'thread_work_total{role="traverse"}' 7 446wait_ready $PORT1 'thread_work_pending{role="scan"}' 0 447wait_ready $PORT1 'thread_busy{role="scan"}' 0 448mv R/debuginfod-rpms/rhel7renamed2 R/debuginfod-rpms/rhel7renamed3 449kill -USR1 $PID1 # scan cycle 450wait_ready $PORT1 'thread_work_total{role="traverse"}' 8 451wait_ready $PORT1 'thread_work_pending{role="scan"}' 0 452wait_ready $PORT1 'thread_busy{role="scan"}' 0 453 454# retest rhel7 455archive_test bc1febfd03ca05e030f0d205f7659db29f8a4b30 /usr/src/debug/hello-1.0/hello.c $SHA 456archive_test f0aa15b8aba4f3c28cac3c2a73801fefa644a9f2 /usr/src/debug/hello-1.0/hello.c $SHA 457 458egrep '(libc.error.*rhel7)|(bc1febfd03ca)|(f0aa15b8aba)' vlog$PORT1 459 460######################################################################## 461 462# Federation mode 463 464# find another unused port 465while true; do 466 PORT2=`expr '(' $RANDOM % 1000 ')' + 9000` 467 ss -atn | fgrep ":$PORT2" || break 468done 469 470export DEBUGINFOD_CACHE_PATH=${PWD}/.client_cache2 471mkdir -p $DEBUGINFOD_CACHE_PATH 472# NB: inherits the DEBUGINFOD_URLS to the first server 473# NB: run in -L symlink-following mode for the L subdir 474env LD_LIBRARY_PATH=$ldpath ${abs_builddir}/../debuginfod/debuginfod $VERBOSE -F -U -d ${DB}_2 -p $PORT2 -L L D > vlog$PORT2 2>&1 & 475PID2=$! 476tempfiles vlog$PORT2 477errfiles vlog$PORT2 478tempfiles ${DB}_2 479wait_ready $PORT2 'ready' 1 480wait_ready $PORT2 'thread_work_total{role="traverse"}' 1 481wait_ready $PORT2 'thread_work_pending{role="scan"}' 0 482wait_ready $PORT2 'thread_busy{role="scan"}' 0 483 484wait_ready $PORT2 'thread_busy{role="http-buildid"}' 0 485wait_ready $PORT2 'thread_busy{role="http-metrics"}' 1 486 487# have clients contact the new server 488export DEBUGINFOD_URLS=http://127.0.0.1:$PORT2 489 490if type bsdtar 2>/dev/null; then 491 # copy in the deb files 492 cp -rvp ${abs_srcdir}/debuginfod-debs/*deb D 493 kill -USR1 $PID2 494 # All debs need to be in the index 495 debs=$(find D -name \*.deb | wc -l) 496 wait_ready $PORT2 'scanned_files_total{source=".deb archive"}' `expr $debs` 497 ddebs=$(find D -name \*.ddeb | wc -l) 498 wait_ready $PORT2 'scanned_files_total{source=".ddeb archive"}' `expr $ddebs` 499 500 # ubuntu 501 archive_test f17a29b5a25bd4960531d82aa6b07c8abe84fa66 "" "" 502fi 503 504rm -rf $DEBUGINFOD_CACHE_PATH 505testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID 506 507# send a request to stress XFF and User-Agent federation relay; 508# we'll grep for the two patterns in vlog$PORT1 509curl -s -H 'User-Agent: TESTCURL' -H 'X-Forwarded-For: TESTXFF' $DEBUGINFOD_URLS/buildid/deaddeadbeef00000000/debuginfo -o /dev/null || true 510 511grep UA:TESTCURL vlog$PORT1 512grep XFF:TESTXFF vlog$PORT1 513 514 515# confirm that first server can't resolve symlinked info in L/ but second can 516BUILDID=`env LD_LIBRARY_PATH=$ldpath ${abs_builddir}/../src/readelf \ 517 -a L/foo | grep 'Build ID' | cut -d ' ' -f 7` 518file L/foo 519file -L L/foo 520export DEBUGINFOD_URLS=http://127.0.0.1:$PORT1 521rm -rf $DEBUGINFOD_CACHE_PATH 522testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID && false || true 523rm -f $DEBUGINFOD_CACHE_PATH/$BUILDID/debuginfo # drop 000-perm negative-hit file 524export DEBUGINFOD_URLS=http://127.0.0.1:$PORT2 525testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID 526 527# test again with scheme free url 528export DEBUGINFOD_URLS=127.0.0.1:$PORT1 529rm -rf $DEBUGINFOD_CACHE_PATH 530testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID && false || true 531rm -f $DEBUGINFOD_CACHE_PATH/$BUILDID/debuginfo # drop 000-perm negative-hit file 532export DEBUGINFOD_URLS=127.0.0.1:$PORT2 533testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID 534 535# test parallel queries in client 536export DEBUGINFOD_CACHE_PATH=${PWD}/.client_cache3 537mkdir -p $DEBUGINFOD_CACHE_PATH 538export DEBUGINFOD_URLS="BAD http://127.0.0.1:$PORT1 127.0.0.1:$PORT1 http://127.0.0.1:$PORT2 DNE" 539 540testrun ${abs_builddir}/debuginfod_build_id_find -e F/prog2 1 541 542######################################################################## 543 544# Fetch some metrics 545curl -s http://127.0.0.1:$PORT1/badapi 546curl -s http://127.0.0.1:$PORT1/metrics 547curl -s http://127.0.0.1:$PORT2/metrics 548curl -s http://127.0.0.1:$PORT1/metrics | grep -q 'http_responses_total.*result.*error' 549curl -s http://127.0.0.1:$PORT1/metrics | grep -q 'http_responses_total.*result.*fdcache' 550curl -s http://127.0.0.1:$PORT2/metrics | grep -q 'http_responses_total.*result.*upstream' 551curl -s http://127.0.0.1:$PORT1/metrics | grep 'http_responses_duration_milliseconds_count' 552curl -s http://127.0.0.1:$PORT1/metrics | grep 'http_responses_duration_milliseconds_sum' 553curl -s http://127.0.0.1:$PORT1/metrics | grep 'http_responses_transfer_bytes_count' 554curl -s http://127.0.0.1:$PORT1/metrics | grep 'http_responses_transfer_bytes_sum' 555curl -s http://127.0.0.1:$PORT1/metrics | grep 'fdcache_' 556curl -s http://127.0.0.1:$PORT1/metrics | grep 'error_count' 557curl -s http://127.0.0.1:$PORT1/metrics | grep 'traversed_total' 558curl -s http://127.0.0.1:$PORT1/metrics | grep 'scanned_bytes_total' 559 560# And generate a few errors into the second debuginfod's logs, for analysis just below 561curl -s http://127.0.0.1:$PORT2/badapi > /dev/null || true 562curl -s http://127.0.0.1:$PORT2/buildid/deadbeef/debuginfo > /dev/null || true 563# NB: this error is used to seed the 404 failure for the survive-404 tests 564 565# Confirm bad artifact types are rejected without leaving trace 566curl -s http://127.0.0.1:$PORT2/buildid/deadbeef/badtype > /dev/null || true 567(curl -s http://127.0.0.1:$PORT2/metrics | grep 'badtype') && false 568 569# Confirm that reused curl connections survive 404 errors. 570# The rm's force an uncached fetch 571rm -f $DEBUGINFOD_CACHE_PATH/$BUILDID/debuginfo .client_cache*/$BUILDID/debuginfo 572testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID 573rm -f $DEBUGINFOD_CACHE_PATH/$BUILDID/debuginfo .client_cache*/$BUILDID/debuginfo 574testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID 575testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID 576testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID 577rm -f $DEBUGINFOD_CACHE_PATH/$BUILDID/debuginfo .client_cache*/$BUILDID/debuginfo 578testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID 579 580# Confirm that some debuginfod client pools are being used 581curl -s http://127.0.0.1:$PORT2/metrics | grep 'dc_pool_op.*reuse' 582 583######################################################################## 584# Corrupt the sqlite database and get debuginfod to trip across its errors 585curl -s http://127.0.0.1:$PORT1/metrics | grep 'sqlite3.*reset' 586ls -al $DB 587dd if=/dev/zero of=$DB bs=1 count=1 588ls -al $DB 589# trigger some random activity that's Sure to get sqlite3 upset 590kill -USR1 $PID1 591wait_ready $PORT1 'thread_work_total{role="traverse"}' 9 592wait_ready $PORT1 'thread_work_pending{role="scan"}' 0 593wait_ready $PORT1 'thread_busy{role="scan"}' 0 594kill -USR2 $PID1 595wait_ready $PORT1 'thread_work_total{role="groom"}' 4 596curl -s http://127.0.0.1:$PORT1/buildid/beefbeefbeefd00dd00d/debuginfo > /dev/null || true 597curl -s http://127.0.0.1:$PORT1/metrics | grep 'error_count.*sqlite' 598 599######################################################################## 600 601# Run the tests again without the servers running. The target file should 602# be found in the cache. 603 604kill -INT $PID1 $PID2 605wait $PID1 $PID2 606PID1=0 607PID2=0 608tempfiles .debuginfod_* 609 610testrun ${abs_builddir}/debuginfod_build_id_find -e F/prog2 1 611 612# check out the debuginfod logs for the new style status lines 613# cat vlog$PORT2 614grep -q 'UA:.*XFF:.*GET /buildid/.* 200 ' vlog$PORT2 615grep -q 'UA:.*XFF:.*GET /metrics 200 ' vlog$PORT2 616grep -q 'UA:.*XFF:.*GET /badapi 503 ' vlog$PORT2 617grep -q 'UA:.*XFF:.*GET /buildid/deadbeef.* 404 ' vlog$PORT2 618 619######################################################################## 620 621# Add some files to the cache that do not fit its naming format. 622# They should survive cache cleaning. 623mkdir $DEBUGINFOD_CACHE_PATH/malformed 624touch $DEBUGINFOD_CACHE_PATH/malformed0 625touch $DEBUGINFOD_CACHE_PATH/malformed/malformed1 626 627# A valid format for an empty buildid subdirectory 628mkdir $DEBUGINFOD_CACHE_PATH/00000000 629touch -d '1970-01-01' $DEBUGINFOD_CACHE_PATH/00000000 # old enough to guarantee nukage 630 631# Trigger a cache clean and run the tests again. The clients should be unable to 632# find the target. 633echo 0 > $DEBUGINFOD_CACHE_PATH/cache_clean_interval_s 634echo 0 > $DEBUGINFOD_CACHE_PATH/max_unused_age_s 635 636testrun ${abs_builddir}/debuginfod_build_id_find -e F/prog 1 637 638testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID2 && false || true 639 640if [ ! -f $DEBUGINFOD_CACHE_PATH/malformed0 ] \ 641 || [ ! -f $DEBUGINFOD_CACHE_PATH/malformed/malformed1 ]; then 642 echo "unrelated files did not survive cache cleaning" 643 exit 1 644fi 645 646if [ -d $DEBUGINFOD_CACHE_PATH/00000000 ]; then 647 echo "failed to rmdir old cache dir" 648 exit 1 649fi 650 651# Test debuginfod without a path list; reuse $PORT1 652env LD_LIBRARY_PATH=$ldpath ${abs_builddir}/../debuginfod/debuginfod $VERBOSE -F -U -d :memory: -p $PORT1 -L -F & 653PID3=$! 654wait_ready $PORT1 'thread_work_total{role="traverse"}' 1 655wait_ready $PORT1 'thread_work_pending{role="scan"}' 0 656wait_ready $PORT1 'thread_busy{role="scan"}' 0 657kill -int $PID3 658wait $PID3 659PID3=0 660 661######################################################################## 662# Test fetching a file using file:// . No debuginfod server needs to be run for 663# this test. 664local_dir=${PWD}/mocktree/buildid/aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd/source/my/path 665mkdir -p ${local_dir} 666echo "int main() { return 0; }" > ${local_dir}/main.c 667 668# first test that is doesn't work, when no DEBUGINFOD_URLS is set 669DEBUGINFOD_URLS="" 670testrun ${abs_top_builddir}/debuginfod/debuginfod-find source aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd /my/path/main.c && false || true 671 672# Now test is with proper DEBUGINFOD_URLS 673DEBUGINFOD_URLS="file://${PWD}/mocktree/" 674filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find source aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd /my/path/main.c` 675cmp $filename ${local_dir}/main.c 676 677exit 0 678