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