]> git.saurik.com Git - apt.git/blame - test/integration/framework
CMake: Switch integration tests and travis over
[apt.git] / test / integration / framework
CommitLineData
8d876415
DK
1#!/bin/sh -- # no runable script, just for vi
2
5d76cee1 3EXIT_CODE=0
8c1dd12c 4
68042532
DK
5while [ -n "$1" ]; do
6 if [ "$1" = "-q" ]; then
7 export MSGLEVEL=2
8 elif [ "$1" = "-v" ]; then
9 export MSGLEVEL=4
10 elif [ "$1" = '--color=no' ]; then
11 export MSGCOLOR='NO'
61e92778
DK
12 elif [ "$1" = '--color=yes' ]; then
13 export MSGCOLOR='YES'
14 elif [ "$1" = '--color' ]; then
15 export MSGCOLOR="$(echo "$2" | tr 'a-z' 'A-Z')"
16 shift
17 elif [ "$1" = '--level' ]; then
18 export MSGLEVEL=$2
19 shift
68042532
DK
20 else
21 echo >&2 "WARNING: Unknown parameter »$1« will be ignored"
22 fi
23 shift
24done
25export MSGLEVEL="${MSGLEVEL:-3}"
26
8d876415 27# we all like colorful messages
61e92778 28if [ "${MSGCOLOR:-YES}" = 'YES' ]; then
27cb4f6c 29 if [ ! -t 1 ]; then # but check that we output to a terminal
1290422a
DK
30 export MSGCOLOR='NO'
31 fi
32fi
33
34
35if [ "$MSGCOLOR" != 'NO' ]; then
36 CERROR="\033[1;31m" # red
37 CWARNING="\033[1;33m" # yellow
38 CMSG="\033[1;32m" # green
39 CINFO="\033[1;96m" # light blue
40 CDEBUG="\033[1;94m" # blue
41 CNORMAL="\033[0;39m" # default system console color
42 CDONE="\033[1;32m" # green
43 CPASS="\033[1;32m" # green
44 CFAIL="\033[1;31m" # red
45 CCMD="\033[1;35m" # pink
682a3bf7 46fi
8d876415 47
de81b2e2
DK
48msgprintf() {
49 local START="$1"
50 local MIDDLE="$2"
51 local END="$3"
52 shift 3
53 if [ -n "$1" ]; then
54 printf "$START " "$1"
d73840dc 55 shift
de81b2e2 56 while [ -n "$1" ]; do
bc8f83a5 57 printf "$MIDDLE " "$(echo "$1" | sed -e 's#^apt\([cfghks]\)#apt-\1#')"
de81b2e2
DK
58 shift
59 done
60 fi
61 printf "${END}"
2a2a7ef4 62}
de81b2e2
DK
63msgdie() { msgprintf "${CERROR}E: %s" '%s' "${CNORMAL}\n" "$@" >&2; exit 1; }
64msgwarn() { msgprintf "${CWARNING}W: %s" '%s' "${CNORMAL}\n" "$@" >&2; }
65msgmsg() { msgprintf "${CMSG}%s" '%s' "${CNORMAL}\n" "$@"; }
66msginfo() { msgprintf "${CINFO}I: %s" '%s' "${CNORMAL}\n" "$@"; }
67msgdebug() { msgprintf "${CDEBUG}D: %s" '%s' "${CNORMAL}\n" "$@"; }
68msgdone() { msgprintf "${CDONE}DONE" '%s' "${CNORMAL}\n" "$@"; }
69msgnwarn() { msgprintf "${CWARNING}W: %s" '%s' "${CNORMAL}" "$@" >&2; }
70msgnmsg() { msgprintf "${CMSG}%s" '%s' "${CNORMAL}" "$@"; }
71msgninfo() { msgprintf "${CINFO}I: %s" '%s' "${CNORMAL}" "$@"; }
72msgndebug() { msgprintf "${CDEBUG}D: %s" '%s' "${CNORMAL}" "$@"; }
73msgtest() { msgprintf "${CINFO}%s" "${CCMD}%s${CINFO}" "…${CNORMAL} " "$@"; }
3c528b91 74msgpass() { printf "${CPASS}PASS${CNORMAL}\n"; }
1501a2c9 75msgreportheader() {
68042532 76 if [ -n "$MSGTEST_MSG" ]; then
1501a2c9 77 test "$1" != 'msgfailoutput' || echo
ae7fce5a
DK
78 if [ -n "$MSGTEST_MSGMSG" ]; then
79 echo "$MSGTEST_MSGMSG"
80 fi
22ac12b2 81 if [ -n "$MSGTEST_GRP" ] && [ "$MSGTEST_GRP" != 'NEXT' ] && [ "$MSGTEST_GRP" != "$MSGTEST_MSG" ]; then
1501a2c9 82 echo "${CFAIL}Part of the test group: $MSGTEST_GRP"
22ac12b2 83 fi
68042532
DK
84 echo -n "$MSGTEST_MSG"
85 unset MSGTEST_MSG
86 fi
1501a2c9
DK
87}
88msgskip() {
89 msgreportheader 'msgskip'
68ba0b7f
DK
90 if [ $# -gt 0 ]; then printf "${CWARNING}SKIP: $*${CNORMAL}\n" >&2;
91 else printf "${CWARNING}SKIP${CNORMAL}\n" >&2; fi
92}
5229b285 93msgfail() {
1501a2c9 94 msgreportheader 'msgfail'
68042532 95 if [ $# -gt 0 ] && [ -n "$1" ]; then printf "${CFAIL}FAIL: $*${CNORMAL}\n" >&2;
3c528b91 96 else printf "${CFAIL}FAIL${CNORMAL}\n" >&2; fi
03aa0847 97 if [ -n "$APT_DEBUG_TESTS" ]; then
896f0ae8 98 runapt $SHELL
03aa0847 99 fi
5229b285
DK
100 EXIT_CODE=$((EXIT_CODE+1));
101}
9beb11aa
DK
102MSGGROUP_LEVEL=0
103msggroup() {
104 if [ -n "$1" ]; then
105 if [ $MSGGROUP_LEVEL = 0 ]; then
106 MSGTEST_GRP='NEXT'
107 fi
108 MSGGROUP_LEVEL=$((MSGGROUP_LEVEL+1));
109 else
110 MSGGROUP_LEVEL=$((MSGGROUP_LEVEL-1));
111 if [ $MSGGROUP_LEVEL = 0 ]; then
112 unset MSGTEST_GRP
113 fi
114 fi
115}
8d876415
DK
116
117# enable / disable Debugging
fc89263e
DK
118if [ $MSGLEVEL -le 0 ]; then
119 msgdie() { true; }
120fi
121if [ $MSGLEVEL -le 1 ]; then
122 msgwarn() { true; }
123 msgnwarn() { true; }
124fi
125if [ $MSGLEVEL -le 2 ]; then
ae7fce5a
DK
126 msgmsg() {
127 MSGTEST_MSGMSG="$(msgprintf "${CMSG}%s" '%s' "${CNORMAL}" "$@")"
128 }
fc89263e 129 msgnmsg() { true; }
9beb11aa
DK
130 msgtest() {
131 MSGTEST_MSG="$(msgprintf "${CINFO}%s" "${CCMD}%s${CINFO}" "…${CNORMAL} " "$@")"
132 if [ "$MSGTEST_GRP" = 'NEXT' ]; then
133 MSGTEST_GRP="$MSGTEST_MSG"
134 fi
135 }
3c528b91 136 msgpass() { printf " ${CPASS}P${CNORMAL}"; }
fc89263e
DK
137fi
138if [ $MSGLEVEL -le 3 ]; then
139 msginfo() { true; }
140 msgninfo() { true; }
141fi
142if [ $MSGLEVEL -le 4 ]; then
143 msgdebug() { true; }
144 msgndebug() { true; }
145fi
146msgdone() {
147 if [ "$1" = "debug" -a $MSGLEVEL -le 4 ] ||
148 [ "$1" = "info" -a $MSGLEVEL -le 3 ] ||
149 [ "$1" = "msg" -a $MSGLEVEL -le 2 ] ||
150 [ "$1" = "warn" -a $MSGLEVEL -le 1 ] ||
151 [ "$1" = "die" -a $MSGLEVEL -le 0 ]; then
152 true;
153 else
3c528b91 154 printf "${CDONE}DONE${CNORMAL}\n";
fc89263e
DK
155 fi
156}
e43a426e
MV
157getaptconfig() {
158 if [ -f ./aptconfig.conf ]; then
5465192b 159 echo "$(readlink -f ./aptconfig.conf)"
e43a426e 160 elif [ -f ../aptconfig.conf ]; then
5465192b
DK
161 echo "$(readlink -f ../aptconfig.conf)"
162 elif [ -f ../../aptconfig.conf ]; then
163 echo "$(readlink -f ../../aptconfig.conf)"
164 elif [ -f "${TMPWORKINGDIRECTORY}/aptconfig.conf" ]; then
165 echo "$(readlink -f "${TMPWORKINGDIRECTORY}/aptconfig.conf")"
166 fi
e43a426e 167}
8d876415
DK
168runapt() {
169 msgdebug "Executing: ${CCMD}$*${CDEBUG} "
846856f4
DK
170 local CMD="$1"
171 shift
3abb6a6a 172 case "$CMD" in
a311fb96 173 sh|aptitude|*/*|command) ;;
3b8eb3bc
DK
174 *) CMD="${BUILDDIRECTORY}/$CMD";;
175 esac
896f0ae8 176 MALLOC_PERTURB_=21 MALLOC_CHECK_=2 APT_CONFIG="$(getaptconfig)" LD_LIBRARY_PATH="${LIBRARYPATH}:${LD_LIBRARY_PATH}" "$CMD" "$@"
8d876415 177}
0390edd5 178runpython3() { runapt command python3 "$@"; }
846856f4
DK
179aptconfig() { runapt apt-config "$@"; }
180aptcache() { runapt apt-cache "$@"; }
181aptcdrom() { runapt apt-cdrom "$@"; }
182aptget() { runapt apt-get "$@"; }
dfd863ea 183aptftparchive() { runapt "${APTFTPARCHIVEBINDIR}/apt-ftparchive" "$@"; }
846856f4
DK
184aptkey() { runapt apt-key "$@"; }
185aptmark() { runapt apt-mark "$@"; }
4f6d26b4 186aptsortpkgs() { runapt apt-sortpkgs "$@"; }
796673c3 187apt() { runapt apt "$@"; }
3b8eb3bc
DK
188apthelper() { runapt "${APTHELPERBINDIR}/apt-helper" "$@"; }
189aptwebserver() { runapt "${APTWEBSERVERBINDIR}/aptwebserver" "$@"; }
190aptitude() { runapt aptitude "$@"; }
8d50b63f 191aptextracttemplates() { runapt apt-extracttemplates "$@"; }
3082603f 192aptinternalsolver() { runapt "${APTINTERNALSOLVER}" "$@"; }
ad7e0941 193aptdumpsolver() { runapt "${APTDUMPSOLVER}" "$@"; }
8e99b22c 194aptinternalplanner() { runapt "${APTINTERNALPLANNER}" "$@"; }
3b8eb3bc 195
158fda31 196dpkg() {
b0be0e09 197 "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" "$@"
158fda31 198}
ce7f128c 199dpkgcheckbuilddeps() {
63c71412 200 command dpkg-checkbuilddeps --admindir="${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg" "$@"
b6b5a542 201}
3fa950f1 202gdb() {
b07aeb1a
DK
203 local CMD
204 case "$1" in
205 aptget) CMD="apt-get";;
206 aptcache) CMD="apt-cache";;
5465192b
DK
207 aptcdrom) CMD="apt-cdrom";;
208 aptconfig) CMD="apt-config";;
b07aeb1a
DK
209 aptmark) CMD="apt-mark";;
210 apthelper) CMD="apt-helper";;
3d8232bf 211 aptftparchive) CMD="apt-ftparchive";;
63c71412 212 dpkg) shift; runapt "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/gdb-dpkg" "$@"; return;;
b07aeb1a
DK
213 *) CMD="$1";;
214 esac
ce928105 215 shift
921a9626
DK
216 if [ "${CMD##*/}" = "$CMD" ]; then
217 CMD="${BUILDDIRECTORY}/${CMD}"
218 fi
219 runapt command gdb --quiet -ex run "$CMD" --args "$CMD" "$@"
ae99ce2e 220}
0340069c 221lastmodification() {
0b45b6e5 222 date -u -d "@$(stat -c '%Y' "${TMPWORKINGDIRECTORY}/$1")" -R
0340069c
DK
223}
224releasefiledate() {
0b45b6e5 225 grep "^${2:-Date}:" "$1" | cut -d' ' -f 2-
0340069c 226}
8d876415 227
8c1dd12c 228exitwithstatus() {
f91bd741
MV
229 # error if we about to overflow, but ...
230 # "255 failures ought to be enough for everybody"
5d76cee1
MV
231 if [ $EXIT_CODE -gt 255 ]; then
232 msgdie "Total failure count $EXIT_CODE too big"
f91bd741 233 fi
5d76cee1 234 exit $((EXIT_CODE <= 255 ? EXIT_CODE : 255));
8c1dd12c
MV
235}
236
804d4a0d
DK
237shellsetedetector() {
238 local exit_status=$?
239 if [ "$exit_status" != '0' ]; then
3c528b91 240 printf >&2 "${CERROR}E: Looks like the testcases ended prematurely with exitcode: ${exit_status}${CNORMAL}\n"
804d4a0d
DK
241 if [ "$EXIT_CODE" = '0' ]; then
242 EXIT_CODE="$exit_status"
243 fi
244 fi
245}
246
b720d0bd 247addtrap() {
8437b7d4
DK
248 if [ "$1" = 'prefix' ]; then
249 CURRENTTRAP="$2 $CURRENTTRAP"
250 else
251 CURRENTTRAP="$CURRENTTRAP $1"
252 fi
804d4a0d 253 trap "shellsetedetector; $CURRENTTRAP exitwithstatus;" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
b720d0bd 254}
8d876415 255
bc8f83a5
DK
256escape_shell() {
257 echo "$@" | sed -e "s#'#'\"'\"'#g"
258}
259
8d876415 260setupenvironment() {
0d303f17
DK
261 # privilege dropping and testing doesn't work if /tmp isn't world-writeable (as e.g. with libpam-tmpdir)
262 if [ -n "$TMPDIR" ] && [ "$(id -u)" = '0' ] && [ "$(stat --format '%a' "$TMPDIR")" != '1777' ]; then
263 unset TMPDIR
264 fi
63c71412 265 TMPWORKINGDIRECTORY="$(mktemp -d)"
bc8f83a5
DK
266 addtrap "cd /; rm -rf '$(escape_shell "$TMPWORKINGDIRECTORY")';"
267 if [ -n "$TMPDIR_ADD" ]; then
268 TMPWORKINGDIRECTORY="${TMPWORKINGDIRECTORY}/${TMPDIR_ADD}"
269 mkdir -p "$TMPWORKINGDIRECTORY"
270 unset TMPDIR_ADD
271 export TMPDIR="$TMPWORKINGDIRECTORY"
272 fi
63c71412 273 msgninfo "Preparing environment for ${0##*/} in ${TMPWORKINGDIRECTORY}…"
5c0dd6fc 274
03aa0847 275 mkdir -m 700 "${TMPWORKINGDIRECTORY}/downloaded"
68ba0b7f
DK
276 if [ "$(id -u)" = '0' ]; then
277 # relax permissions so that running as root with user switching works
278 umask 022
03aa0847
DK
279 chmod 711 "$TMPWORKINGDIRECTORY"
280 chown _apt:root "${TMPWORKINGDIRECTORY}/downloaded"
68ba0b7f
DK
281 fi
282
63c71412 283 TESTDIRECTORY="$(readlink -f "$(dirname $0)")"
5c0dd6fc 284 # allow overriding the default BUILDDIR location
63c71412 285 SOURCEDIRECTORY="${APT_INTEGRATION_TESTS_SOURCE_DIR:-"${TESTDIRECTORY}/../../"}"
dfd863ea
JAK
286 BUILDDIRECTORY="${APT_INTEGRATION_TESTS_BUILD_DIR:-"${TESTDIRECTORY}/../../build/cmdline"}"
287 LIBRARYPATH="${APT_INTEGRATION_TESTS_LIBRARY_PATH:-"${BUILDDIRECTORY}/../apt-pkg"}"
288 METHODSDIR="${APT_INTEGRATION_TESTS_METHODS_DIR:-"${BUILDDIRECTORY}/../methods"}"
63c71412 289 APTHELPERBINDIR="${APT_INTEGRATION_TESTS_LIBEXEC_DIR:-"${BUILDDIRECTORY}"}"
dfd863ea
JAK
290 APTWEBSERVERBINDIR="${APT_INTEGRATION_TESTS_WEBSERVER_BIN_DIR:-"${BUILDDIRECTORY}/../test/interactive-helper"}"
291 APTFTPARCHIVEBINDIR="${APT_INTEGRATION_TESTS_FTPARCHIVE_BIN_DIR:-"${BUILDDIRECTORY}/../ftparchive"}"
292 APTINTERNALSOLVER="${APT_INTEGRATION_TESTS_INTERNAL_SOLVER:-"${BUILDDIRECTORY}/solvers/apt"}"
293 APTDUMPSOLVER="${APT_INTEGRATION_TESTS_DUMP_SOLVER:-"${BUILDDIRECTORY}/solvers/dump"}"
294 APTINTERNALPLANNER="${APT_INTEGRATION_TESTS_INTERNAL_PLANNER:-"${BUILDDIRECTORY}/planners/apt"}"
8d876415 295 test -x "${BUILDDIRECTORY}/apt-get" || msgdie "You need to build tree first"
5c0dd6fc
MV
296 # -----
297
63c71412 298 cd "$TMPWORKINGDIRECTORY"
cd725954 299 mkdir rootdir aptarchive keys
8d876415 300 cd rootdir
b29c3712 301 mkdir -p etc/apt/apt.conf.d etc/apt/sources.list.d etc/apt/trusted.gpg.d etc/apt/preferences.d
84255101 302 mkdir -p usr/bin var/cache var/lib var/log var/crash tmp
cffea9af 303 mkdir -p var/lib/dpkg/info var/lib/dpkg/updates var/lib/dpkg/triggers
b327c569 304 mkdir -p usr/lib/apt/solvers usr/lib/apt/planners
cd725954 305 touch var/lib/dpkg/available
63c71412 306 ln -s "${METHODSDIR}" usr/lib/apt/methods
b327c569
DK
307 ln -s "${APTDUMPSOLVER}" usr/lib/apt/solvers/dump
308 ln -s "${APTDUMPSOLVER}" usr/lib/apt/planners/dump
309 ln -s "${APTINTERNALSOLVER}" usr/lib/apt/solvers/apt
310 ln -s "${APTINTERNALPLANNER}" usr/lib/apt/planners/apt
311 echo "Dir::Bin::Solvers \"${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/solvers\";" >> ../aptconfig.conf
312 echo "Dir::Bin::Planners \"${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/planners\";" >> ../aptconfig.conf
291a386f
MV
313 # use the autoremove from the BUILDDIRECTORY if its there, otherwise
314 # system
63c71412
DK
315 if [ -e "${BUILDDIRECTORY}/../../debian/apt.conf.autoremove" ]; then
316 ln -s "${BUILDDIRECTORY}/../../debian/apt.conf.autoremove" etc/apt/apt.conf.d/01autoremove
291a386f
MV
317 else
318 ln -s /etc/apt/apt.conf.d/01autoremove etc/apt/apt.conf.d/01autoremove
319 fi
8d876415 320 cd ..
63c71412
DK
321 local BASENAME="${0##*/}"
322 local PACKAGESFILE="Packages-${BASENAME#*-}"
53ea1b56
DK
323 if [ -f "${TESTDIRECTORY}/${PACKAGESFILE}" ]; then
324 cp "${TESTDIRECTORY}/${PACKAGESFILE}" aptarchive/Packages
8f8169ac 325 fi
63c71412 326 local SOURCESSFILE="Sources-${BASENAME#*-}"
53ea1b56
DK
327 if [ -f "${TESTDIRECTORY}/${SOURCESSFILE}" ]; then
328 cp "${TESTDIRECTORY}/${SOURCESSFILE}" aptarchive/Sources
8f8169ac 329 fi
3abb6a6a
DK
330 find "$TESTDIRECTORY" \( -name '*.pub' -o -name '*.sec' \) -exec cp '{}' keys/ \;
331 chmod 644 keys/*
63c71412 332 ln -s "${TMPWORKINGDIRECTORY}/keys/joesixpack.pub" rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
d6cf2345 333
b4f91d4d 334 echo "Dir \"${TMPWORKINGDIRECTORY}/rootdir\";" >> aptconfig.conf
8d876415 335 echo "APT::Get::Show-User-Simulation-Note \"false\";" >> aptconfig.conf
9d2a8a73 336 echo "Dir::Bin::Methods \"${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/methods\";" >> aptconfig.conf
23e64f6d
DK
337 # either store apt-key were we can access it, even if we run it as a different user
338 #cp "${BUILDDIRECTORY}/apt-key" "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/"
339 #chmod o+rx "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apt-key"
340 #echo "Dir::Bin::apt-key \"${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apt-key\";" >> aptconfig.conf
341 # destroys coverage reporting though, so we disable changing user for the calling gpgv
342 echo "Dir::Bin::apt-key \"${BUILDDIRECTORY}/apt-key\";" >> aptconfig.conf
68ba0b7f 343 if [ "$(id -u)" = '0' ]; then
007d8b48
DK
344 echo 'Binary::gpgv::APT::Sandbox::User "root";' >> aptconfig.conf
345 # same for the solver executables
346 echo 'APT::Solver::RunAsUser "root";' >> aptconfig.conf
8e99b22c 347 echo 'APT::Planner::RunAsUser "root";' >> aptconfig.conf
68ba0b7f 348 fi
b0be0e09 349
63c71412 350 cat > "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" <<EOF
b0be0e09
DK
351#!/bin/sh
352set -e
3abb6a6a 353if [ -r '${TMPWORKINGDIRECTORY}/noopchroot.so' ]; then
63c71412 354 if [ -n "\$LD_LIBRARY_PATH" ]; then
3abb6a6a 355 export LD_LIBRARY_PATH='${TMPWORKINGDIRECTORY}:'"\${LD_LIBRARY_PATH}"
b0be0e09 356 else
3abb6a6a 357 export LD_LIBRARY_PATH='${TMPWORKINGDIRECTORY}'
b0be0e09 358 fi
921a9626 359 if [ -n "\$LD_PRELOAD" ]; then
63c71412 360 export LD_PRELOAD="noopchroot.so \${LD_PRELOAD}"
921a9626 361 else
63c71412 362 export LD_PRELOAD="noopchroot.so"
921a9626
DK
363 fi
364fi
63c71412
DK
365EOF
366 cp "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/gdb-dpkg"
367 cat >> "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" <<EOF
3abb6a6a
DK
368exec fakeroot '${DPKG:-dpkg}' --root='${TMPWORKINGDIRECTORY}/rootdir' \\
369 --log='${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log' \\
63c71412
DK
370 --force-not-root --force-bad-path "\$@"
371EOF
372 cat >> "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/gdb-dpkg" <<EOF
3abb6a6a
DK
373exec fakeroot gdb --quiet -ex run '${DPKG:-dpkg}' --args '${DPKG:-dpkg}' --root='${TMPWORKINGDIRECTORY}/rootdir' \\
374 --log='${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log' \\
b0be0e09
DK
375 --force-not-root --force-bad-path "\$@"
376EOF
921a9626 377 chmod +x "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/gdb-dpkg"
b0be0e09
DK
378 echo "Dir::Bin::dpkg \"${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg\";" > rootdir/etc/apt/apt.conf.d/99dpkg
379
533fe3d1
DK
380 {
381 if ! command dpkg --assert-multi-arch >/dev/null 2>&1; then
382 echo "DPKG::options:: \"--force-architecture\";" # Added to test multiarch before dpkg is ready for it…
383 fi
87d6947d 384 echo 'quiet "0";'
533fe3d1
DK
385 echo 'quiet::NoUpdate "true";'
386 echo 'quiet::NoStatistic "true";'
387 # too distracting for users, but helpful to detect changes
388 echo 'Acquire::Progress::Ignore::ShowErrorText "true";'
389 echo 'Acquire::Progress::Diffpercent "true";'
390 # in testcases, it can appear as if localhost has a rotation setup,
391 # hide this as we can't really deal with it properly
392 echo 'Acquire::Failure::ShowIP "false";'
ebca2f25
DK
393 # fakeroot can't fake everything, so disabled in production but good for tests
394 echo 'APT::Sandbox::Verify "true";'
533fe3d1 395 } >> aptconfig.conf
d6cf2345 396
68ba0b7f
DK
397 cp "${TESTDIRECTORY}/apt.pem" "${TMPWORKINGDIRECTORY}/rootdir/etc/webserver.pem"
398 if [ "$(id -u)" = '0' ]; then
399 chown _apt:root "${TMPWORKINGDIRECTORY}/rootdir/etc/webserver.pem"
400 fi
401 echo "Acquire::https::CaInfo \"${TMPWORKINGDIRECTORY}/rootdir/etc/webserver.pem\";" > rootdir/etc/apt/apt.conf.d/99https
d6cf2345 402 echo "Apt::Cmd::Disable-Script-Warning \"1\";" > rootdir/etc/apt/apt.conf.d/apt-binary
08fcf962 403 export APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=no
23d35ec1 404 echo 'Acquire::Connect::AddrConfig "false";' > rootdir/etc/apt/apt.conf.d/connect-addrconfig
493a813e 405
276e51dd 406 configcompression '.' 'gz' #'bz2' 'lzma' 'xz'
51c04562 407 confighashes 'SHA256' # these are tests, not security best-practices
77a45beb 408
4bb006d1 409 # create some files in /tmp and look at user/group to get what this means
eab57e08 410 TEST_DEFAULT_USER="$(id -un)"
4bb006d1
DK
411 if [ "$(uname)" = 'GNU/kFreeBSD' ]; then
412 TEST_DEFAULT_GROUP='root'
413 else
eab57e08 414 TEST_DEFAULT_GROUP="$(id -gn)"
4bb006d1
DK
415 fi
416
ce7f128c 417 # cleanup the environment a bit
995a4bf6 418 # prefer our apt binaries over the system apt binaries
8c617819 419 export PATH="${BUILDDIRECTORY}:${PATH}:/usr/local/sbin:/usr/sbin:/sbin"
be233796 420 export LC_ALL=C.UTF-8
3b8eb3bc 421 unset LANGUAGE APT_CONFIG
ce7f128c 422 unset GREP_OPTIONS DEB_BUILD_PROFILES
59f57473 423 unset http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy
0cbb7e29
JAK
424
425 # If gpgv supports --weak-digest, pass it to make sure we can disable SHA1
426 if aptkey verify --weak-digest SHA1 --help 2>/dev/null >/dev/null; then
427 echo 'Acquire::gpgv::Options { "--weak-digest"; "sha1"; };' > rootdir/etc/apt/apt.conf.d/no-sha1
428 fi
429
5a23c56d
DK
430 # most tests just need one signed Release file, not both
431 export APT_DONT_SIGN='Release.gpg'
432
60b48d4f
DK
433 if [ -r "${TESTDIRECTORY}/extra-environment" ]; then
434 . "${TESTDIRECTORY}/extra-environment"
435 fi
436
8d876415
DK
437 msgdone "info"
438}
439
ea65d079
DK
440getarchitecture() {
441 if [ "$1" = "native" -o -z "$1" ]; then
442 eval `aptconfig shell ARCH APT::Architecture`
443 if [ -n "$ARCH" ]; then
444 echo $ARCH
445 else
5834d7a1 446 dpkg --print-architecture
ea65d079
DK
447 fi
448 else
449 echo $1
450 fi
451}
452
53ea1b56 453getarchitectures() {
081c9d44 454 aptconfig dump --no-empty --format '%v%n' APT::Architecture APT::Architectures | sort -u | tr '\n' ' '
53ea1b56
DK
455}
456
3dcdc1f9
DK
457getarchitecturesfromcommalist() {
458 echo "$1" | sed -e 's#,#\n#g' | sed -e "s/^native\$/$(getarchitecture 'native')/"
459}
460
8d876415 461configarchitecture() {
18908589
DK
462 {
463 echo "APT::Architecture \"$(getarchitecture $1)\";"
464 while [ -n "$1" ]; do
465 echo "APT::Architectures:: \"$(getarchitecture $1)\";"
466 shift
467 done
468 } >rootdir/etc/apt/apt.conf.d/01multiarch.conf
53ea1b56
DK
469 configdpkg
470}
471
472configdpkg() {
473 if [ ! -e rootdir/var/lib/dpkg/status ]; then
63c71412
DK
474 local BASENAME="${0##*/}"
475 local STATUSFILE="status-${BASENAME#*-}"
53ea1b56
DK
476 if [ -f "${TESTDIRECTORY}/${STATUSFILE}" ]; then
477 cp "${TESTDIRECTORY}/${STATUSFILE}" rootdir/var/lib/dpkg/status
478 else
479 echo -n > rootdir/var/lib/dpkg/status
480 fi
481 fi
18908589 482 rm -f rootdir/etc/apt/apt.conf.d/00foreigndpkg
846856f4 483 if command dpkg --assert-multi-arch >/dev/null 2>&1 ; then
53ea1b56 484 local ARCHS="$(getarchitectures)"
87f99f6f
DK
485 local DPKGARCH="$(dpkg --print-architecture)"
486 # this ensures that even if multi-arch isn't active in the view
487 # of apt, given that dpkg can't be told which arch is native
488 # the arch apt treats as native might be foreign for dpkg
489 for ARCH in ${ARCHS}; do
490 if [ "${ARCH}" != "${DPKGARCH}" ]; then
491 if ! dpkg --add-architecture ${ARCH} >/dev/null 2>&1; then
492 # old-style used e.g. in Ubuntu-P – and as it seems travis
493 echo "DPKG::options:: \"--foreign-architecture\";" >> rootdir/etc/apt/apt.conf.d/00foreigndpkg
494 echo "DPKG::options:: \"${ARCH}\";" >> rootdir/etc/apt/apt.conf.d/00foreigndpkg
feae193b 495 fi
87f99f6f
DK
496 fi
497 done
498 # if multi-arch make sure dpkg can detect itself as capable of it
499 if echo "$ARCHS" | grep -E -q '[^ ]+ [^ ]+'; then
53ea1b56 500 if [ "0" = "$(dpkg -l dpkg 2> /dev/null | grep '^i' | wc -l)" ]; then
05343a22
DK
501 # dpkg doesn't really check the version as long as it is fully installed,
502 # but just to be sure we choose one above the required version
503 insertinstalledpackage 'dpkg' "all" '1.16.2+fake'
53ea1b56
DK
504 fi
505 fi
506 fi
8d876415
DK
507}
508
0c787570
DK
509configdpkgnoopchroot() {
510 # create a library to noop chroot() and rewrite maintainer script executions
511 # via execvp() as used by dpkg as we don't want our rootdir to be a fullblown
512 # chroot directory dpkg could chroot into to execute the maintainer scripts
513 msgtest 'Building library to preload to make maintainerscript work in' 'dpkg'
63c71412 514 cat > noopchroot.c << EOF
0c787570
DK
515#define _GNU_SOURCE
516#include <stdio.h>
517#include <stdlib.h>
518#include <string.h>
519#include <dlfcn.h>
520
521static char * chrootdir = NULL;
522
523int chroot(const char *path) {
524 printf("WARNING: CHROOTing to %s was ignored!\n", path);
525 free(chrootdir);
526 chrootdir = strdup(path);
527 return 0;
528}
529int execvp(const char *file, char *const argv[]) {
530 static int (*func_execvp) (const char *, char * const []) = NULL;
531 if (func_execvp == NULL)
532 func_execvp = (int (*) (const char *, char * const [])) dlsym(RTLD_NEXT, "execvp");
533 if (chrootdir == NULL || strncmp(file, "/var/lib/dpkg/", strlen("/var/lib/dpkg/")) != 0)
534 return func_execvp(file, argv);
535 printf("REWRITE execvp call %s into %s\n", file, chrootdir);
950733c9
JAK
536 char *newfile;
537 if (asprintf(&newfile, "%s%s", chrootdir, file) == -1) {
538 perror("asprintf");
539 return -1;
540 }
b0be0e09 541 char const * const baseadmindir = "/var/lib/dpkg";
950733c9
JAK
542 char *admindir;
543 if (asprintf(&admindir, "%s%s", chrootdir, baseadmindir) == -1) {
544 perror("asprintf");
545 return -1;
546 }
b0be0e09 547 setenv("DPKG_ADMINDIR", admindir, 1);
0c787570
DK
548 return func_execvp(newfile, argv);
549}
550EOF
a66e1837 551 testempty --nomsg gcc -Wall -Wextra -fPIC -shared -o noopchroot.so noopchroot.c -ldl
0c787570 552}
276e51dd 553configcompression() {
bdc42211
DK
554 if [ "$1" = 'ALL' ]; then
555 configcompression '.' $(aptconfig dump APT::Compressor --format '%t %v%n' | sed -n 's#^Extension \.\(.*\)$#\1#p')
556 return
557 fi
abec2980 558 local CMD='apthelper cat-file -C'
276e51dd
DK
559 while [ -n "$1" ]; do
560 case "$1" in
3c528b91 561 '.') printf ".\t.\tcat\n";;
abec2980
DK
562 'gz') printf "gzip\tgz\t$CMD $1\n";;
563 'bz2') printf "bzip2\tbz2\t$CMD $1\n";;
564 *) printf "$1\t$1\t$CMD $1\n";;
276e51dd
DK
565 esac
566 shift
63c71412 567 done > "${TMPWORKINGDIRECTORY}/rootdir/etc/testcase-compressor.conf"
276e51dd 568}
c5ede4ca
DK
569confighashes() {
570 {
571 echo 'APT::FTPArchive {'
572 {
573 while [ -n "$1" ]; do
574 printf "$1" | tr 'a-z' 'A-Z'
575 printf "\t\"true\";\n"
576 shift
577 done
578 for h in 'MD5' 'SHA1' 'SHA256' 'SHA512'; do
579 printf "$h\t\"false\";\n"
580 done
581 } | awk '!x[$1]++'
582 echo '};'
583 } >> "${TMPWORKINGDIRECTORY}/rootdir/etc/apt/apt.conf.d/ftparchive-hashes.conf"
584}
5f982b9d
DK
585forcecompressor() {
586 COMPRESSOR="$1"
912a6131 587 COMPRESS="$1"
abec2980 588 COMPRESSOR_CMD="apthelper cat-file -C $1"
5f982b9d
DK
589 case $COMPRESSOR in
590 gzip) COMPRESS='gz';;
591 bzip2) COMPRESS='bz2';;
5f982b9d
DK
592 esac
593 local CONFFILE="${TMPWORKINGDIRECTORY}/rootdir/etc/apt/apt.conf.d/00force-compressor"
594 echo "Acquire::CompressionTypes::Order { \"${COMPRESS}\"; };
912a6131 595Dir::Bin::uncompressed \"/does/not/exist\";" > "$CONFFILE"
b2fd8524
DK
596 for COMP in $(aptconfig dump 'APT::Compressor' --format '%f%n' | cut -d':' -f 5 | uniq); do
597 if [ -z "$COMP" -o "$COMP" = '.' -o "$COMP" = "$COMPRESSOR" ]; then continue; fi
598 echo "Dir::Bin::${COMP} \"/does/not/exist\";" >> "$CONFFILE"
599 echo "APT::Compressor::${COMP}::Name \"${COMP}-disabled\";" >> "$CONFFILE"
600 done
5f982b9d
DK
601}
602
b8242321 603_setupsimplenativepackage() {
75954ae2
DK
604 local NAME="$1"
605 local ARCH="$2"
606 local VERSION="$3"
607 local RELEASE="${4:-unstable}"
608 local DEPENDENCIES="$5"
14109555 609 local DESCRIPTION="${6:-"an autogenerated dummy ${NAME}=${VERSION}/${RELEASE}
18908589
DK
610 If you find such a package installed on your system,
611 something went horribly wrong! They are autogenerated
3d284148 612 und used only by testcases and serve no other purpose…"}"
18908589 613
75954ae2 614 local SECTION="${7:-others}"
d67004e0 615 local PRIORITY="${8:-optional}"
63c71412
DK
616 local FILE_TREE="$9"
617 local COMPRESS_TYPE="${10:-gzip}"
75954ae2 618 local DISTSECTION
63c71412 619 if [ "$SECTION" = "${SECTION#*/}" ]; then
75954ae2
DK
620 DISTSECTION="main"
621 else
63c71412 622 DISTSECTION="${SECTION%/*}"
75954ae2 623 fi
63c71412 624 local BUILDDIR="${TMPWORKINGDIRECTORY}/incoming/${NAME}-${VERSION}"
b761356f 625
63c71412
DK
626 mkdir -p "$BUILDDIR/debian/source"
627 echo "* most suckless software product ever" > "${BUILDDIR}/FEATURES"
b761356f 628 echo "#!/bin/sh
63c71412 629echo '$NAME says \"Hello!\"'" > "${BUILDDIR}/${NAME}"
b761356f 630
0340069c 631 echo "Copyleft by Joe Sixpack $(date -u +%Y)" > "${BUILDDIR}/debian/copyright"
b761356f
DK
632 echo "$NAME ($VERSION) $RELEASE; urgency=low
633
634 * Initial release
635
0340069c 636 -- Joe Sixpack <joe@example.org> $(date -u -R)" > "${BUILDDIR}/debian/changelog"
63c71412
DK
637 {
638 echo "Source: $NAME
d67004e0 639Priority: $PRIORITY
b761356f 640Maintainer: Joe Sixpack <joe@example.org>
63c71412
DK
641Standards-Version: 3.9.3"
642 if [ "$SECTION" != '<none>' ]; then
643 echo "Section: $SECTION"
644 fi
645 local BUILDDEPS="$(echo "$DEPENDENCIES" | grep '^Build-')"
646 test -z "$BUILDDEPS" || echo "$BUILDDEPS"
647 echo "
648Package: $NAME"
b761356f 649
63c71412
DK
650 if [ "$ARCH" = 'all' ]; then
651 echo "Architecture: all"
652 else
653 echo "Architecture: any"
654 fi
655 local DEPS="$(echo "$DEPENDENCIES" | grep -v '^Build-')"
656 test -z "$DEPS" || echo "$DEPS"
657 echo "Description: $DESCRIPTION"
658 } > "${BUILDDIR}/debian/control"
01f520ce 659
63c71412 660 echo '3.0 (native)' > "${BUILDDIR}/debian/source/format"
b8242321
DK
661}
662
663setupsimplenativepackage() {
664 _setupsimplenativepackage "$@"
665 local NAME="$1"
666 local VERSION="$3"
667 local BUILDDIR="${TMPWORKINGDIRECTORY}/incoming/${NAME}-${VERSION}"
668 test -e "${BUILDDIR}/debian/compat" || echo '7' > "${BUILDDIR}/debian/compat"
669 test -e "${BUILDDIR}/debian/rules" || cp /usr/share/doc/debhelper/examples/rules.tiny "${BUILDDIR}/debian/rules"
670}
671
672buildsimplenativepackage() {
673 local NAME="$1"
674 local ARCH="$2"
675 local VERSION="$3"
676 local RELEASE="${4:-unstable}"
677 local DEPENDENCIES="$5"
678 local DESCRIPTION="$6"
679 local SECTION="${7:-others}"
680 local PRIORITY="${8:-optional}"
681 local FILE_TREE="$9"
682 local COMPRESS_TYPE="${10:-gzip}"
683 local DISTSECTION
684 if [ "$SECTION" = "${SECTION#*/}" ]; then
685 DISTSECTION="main"
686 else
687 DISTSECTION="${SECTION%/*}"
688 fi
689 local BUILDDIR="${TMPWORKINGDIRECTORY}/incoming/${NAME}-${VERSION}"
690 msgtest "Build source package in version ${VERSION} for ${RELEASE} in ${DISTSECTION}" "$NAME"
691 _setupsimplenativepackage "$@"
63c71412 692 cd "${BUILDDIR}/.."
0c787570
DK
693 testsuccess --nomsg dpkg-source -b ${NAME}-${VERSION}
694 cd - >/dev/null
63c71412 695 sed -n 's#^dpkg-source: info: building [^ ]\+ in ##p' "${TMPWORKINGDIRECTORY}/rootdir/tmp/testsuccess.output" \
f1828b69 696 | while read SRC; do
63c71412 697 echo "pool/${SRC}" >> "${BUILDDIR}/../${RELEASE}.${DISTSECTION}.srclist"
f1828b69 698# if expr match "${SRC}" '.*\.dsc' >/dev/null 2>&1; then
33a22672 699# aptkey --keyring ./keys/joesixpack.pub --secret-keyring ./keys/joesixpack.sec --quiet --readonly \
bd7fb5aa 700# adv --yes --default-key 'Joe Sixpack' \
f1828b69
DK
701# --clearsign -o "${BUILDDIR}/../${SRC}.sign" "${BUILDDIR}/../$SRC"
702# mv "${BUILDDIR}/../${SRC}.sign" "${BUILDDIR}/../$SRC"
703# fi
b761356f 704 done
84aa13f4 705
3dcdc1f9 706 for arch in $(getarchitecturesfromcommalist "$ARCH"); do
0c787570 707 msgtest "Build binary package for ${RELEASE} in ${SECTION}" "$NAME"
63c71412
DK
708 rm -rf "${BUILDDIR}/debian/tmp"
709 mkdir -p "${BUILDDIR}/debian/tmp/DEBIAN" "${BUILDDIR}/debian/tmp/usr/share/doc/${NAME}" "${BUILDDIR}/debian/tmp/usr/bin"
710 cp "${BUILDDIR}/debian/copyright" "${BUILDDIR}/debian/changelog" "${BUILDDIR}/FEATURES" "${BUILDDIR}/debian/tmp/usr/share/doc/${NAME}"
711 cp "${BUILDDIR}/${NAME}" "${BUILDDIR}/debian/tmp/usr/bin/${NAME}-${arch}"
42c1513b 712 if [ -n "$FILE_TREE" ]; then
63c71412 713 cp -ar "$FILE_TREE" "${BUILDDIR}/debian/tmp"
42c1513b 714 fi
42c1513b 715
63c71412
DK
716 (cd "${BUILDDIR}"; dpkg-gencontrol -DArchitecture=$arch)
717 (cd "${BUILDDIR}/debian/tmp"; md5sum $(find usr/ -type f) > DEBIAN/md5sums)
846856f4 718 local LOG="${BUILDDIR}/../${NAME}_${VERSION}_${arch}.dpkg-deb.log"
d56e2917 719 # ensure the right permissions as dpkg-deb insists
63c71412
DK
720 chmod 755 "${BUILDDIR}/debian/tmp/DEBIAN"
721 testsuccess --nomsg dpkg-deb -Z${COMPRESS_TYPE} --build "${BUILDDIR}/debian/tmp" "${BUILDDIR}/.."
722 echo "pool/${NAME}_${VERSION}_${arch}.deb" >> "${BUILDDIR}/../${RELEASE}.${DISTSECTION}.pkglist"
84aa13f4
DK
723 done
724
b8242321
DK
725 local NM
726 if [ "$(echo "$NAME" | cut -c 1-3)" = 'lib' ]; then
727 NM="$(echo "$NAME" | cut -c 1-4)"
728 else
729 NM="$(echo "$NAME" | cut -c 1)"
730 fi
d56e2917 731 local CHANGEPATH="${BUILDDIR}/../${DISTSECTION}/${NM}/${NAME}/${NAME}_${VERSION}"
63c71412
DK
732 mkdir -p "$CHANGEPATH"
733 cp "${BUILDDIR}/debian/changelog" "$CHANGEPATH"
5a635ee4 734 rm -rf "${BUILDDIR}"
b761356f 735 msgdone "info"
75954ae2
DK
736}
737
738buildpackage() {
739 local BUILDDIR=$1
740 local RELEASE=$2
741 local SECTION=$3
ea65d079 742 local ARCH=$(getarchitecture $4)
846856f4
DK
743 local PKGNAME="$(echo "$BUILDDIR" | grep -o '[^/]*$')"
744 local BUILDLOG="$(readlink -f "${BUILDDIR}/../${PKGNAME}_${RELEASE}_${SECTION}.dpkg-bp.log")"
0c787570 745 msgtest "Build package for ${RELEASE} in ${SECTION}" "$PKGNAME"
63c71412 746 cd "$BUILDDIR"
75954ae2
DK
747 if [ "$ARCH" = "all" ]; then
748 ARCH="$(dpkg-architecture -qDEB_HOST_ARCH 2> /dev/null)"
749 fi
0c787570 750 testsuccess --nomsg dpkg-buildpackage -uc -us -a$ARCH
63c71412
DK
751 cp "${TMPWORKINGDIRECTORY}/rootdir/tmp/testsuccess.output" "$BUILDLOG"
752 local PKGS="$(grep '^dpkg-deb: building package' "$BUILDLOG" | cut -d'/' -f 2 | sed -e "s#'\.##")"
753 local SRCS="$(grep '^dpkg-source: info: building' "$BUILDLOG" | grep -o '[a-z0-9._+~-]*$')"
ce9864a8 754 cd - > /dev/null
b7899b00 755 for PKG in $PKGS; do
63c71412 756 echo "pool/${PKG}" >> "${TMPWORKINGDIRECTORY}/incoming/${RELEASE}.${SECTION}.pkglist"
b7899b00
DK
757 done
758 for SRC in $SRCS; do
63c71412 759 echo "pool/${SRC}" >> "${TMPWORKINGDIRECTORY}/incoming/${RELEASE}.${SECTION}.srclist"
b7899b00 760 done
ce9864a8
DK
761}
762
763buildaptarchive() {
ce9864a8 764 if [ -d incoming ]; then
846856f4 765 buildaptarchivefromincoming "$@"
ce9864a8 766 else
846856f4 767 buildaptarchivefromfiles "$@"
ce9864a8
DK
768 fi
769}
770
771createaptftparchiveconfig() {
63c71412 772 local COMPRESSORS="$(cut -d' ' -f 1 "${TMPWORKINGDIRECTORY}/rootdir/etc/testcase-compressor.conf" | tr '\n' ' ')"
016bea82
DK
773 local COMPRESSORS="${COMPRESSORS%* }"
774 local ARCHS="$(getarchitectures)"
c5ede4ca
DK
775 cat > ftparchive.conf <<EOF
776Dir {
777 ArchiveDir "$(readlink -f .)";
778 CacheDir "$(readlink -f ..)";
779 FileListDir "$(readlink -f pool/)";
b7899b00
DK
780};
781Default {
c5ede4ca
DK
782 Packages::Compress "$COMPRESSORS";
783 Sources::Compress "$COMPRESSORS";
784 Contents::Compress "$COMPRESSORS";
785 Translation::Compress "$COMPRESSORS";
18331adf 786 LongDescription "false";
ce9864a8
DK
787};
788TreeDefault {
789 Directory "pool/";
790 SrcDirectory "pool/";
791};
c5ede4ca 792EOF
b7899b00 793 for DIST in $(find ./pool/ -maxdepth 1 -name '*.pkglist' -type f | cut -d'/' -f 3 | cut -d'.' -f 1 | sort | uniq); do
63c71412
DK
794 cat <<EOF
795tree "dists/$DIST" {
1dd20368 796 Architectures "$ARCHS all source";
63c71412
DK
797 FileList "${DIST}.\$(SECTION).pkglist";
798 SourceFileList "${DIST}.\$(SECTION).srclist";
799 Sections "$(find ./pool/ -maxdepth 1 -name "${DIST}.*.pkglist" -type f | cut -d'/' -f 3 | cut -d'.' -f 2 | sort | uniq | tr '\n' ' ')";
800};
801EOF
802 done >> ftparchive.conf
ce9864a8
DK
803}
804
805buildaptftparchivedirectorystructure() {
b7899b00
DK
806 local DISTS="$(grep -i '^tree ' ftparchive.conf | cut -d'/' -f 2 | sed -e 's#".*##')"
807 for DIST in $DISTS; do
808 local SECTIONS="$(grep -i -A 5 "dists/$DIST" ftparchive.conf | grep -i 'Sections' | cut -d'"' -f 2)"
809 for SECTION in $SECTIONS; do
810 local ARCHS="$(grep -A 5 "dists/$DIST" ftparchive.conf | grep Architectures | cut -d'"' -f 2 | sed -e 's#source##')"
811 for ARCH in $ARCHS; do
63c71412 812 mkdir -p "dists/${DIST}/${SECTION}/binary-${ARCH}"
b7899b00 813 done
63c71412
DK
814 mkdir -p "dists/${DIST}/${SECTION}/source"
815 mkdir -p "dists/${DIST}/${SECTION}/i18n"
b7899b00 816 done
ce9864a8 817 done
ce9864a8
DK
818}
819
9b78cda6 820insertpackage() {
10e100e5 821 local RELEASES="$1"
9b78cda6
DK
822 local NAME="$2"
823 local ARCH="$3"
824 local VERSION="$4"
825 local DEPENDENCIES="$5"
d67004e0 826 local PRIORITY="${6:-optional}"
10e100e5 827 local DESCRIPTION="${7:-"an autogenerated dummy ${NAME}=${VERSION}/${RELEASES}
18908589
DK
828 If you find such a package installed on your system,
829 something went horribly wrong! They are autogenerated
3d284148 830 und used only by testcases and serve no other purpose…"}"
d67004e0 831 local ARCHS=""
10e100e5
DK
832 for RELEASE in $(printf '%s' "$RELEASES" | tr ',' '\n'); do
833 if [ "$RELEASE" = 'installed' ]; then
834 insertinstalledpackage "$2" "$3" "$4" "$5" "$6" "$7"
835 continue
d67004e0 836 fi
10e100e5 837 for arch in $(getarchitecturesfromcommalist "$ARCH"); do
1dd20368 838 if [ "$arch" = 'none' ]; then
10e100e5
DK
839 ARCHS="$(getarchitectures)"
840 else
841 ARCHS="$arch"
842 fi
843 for BUILDARCH in $ARCHS; do
844 local PPATH="aptarchive/dists/${RELEASE}/main/binary-${BUILDARCH}"
63c71412
DK
845 mkdir -p "$PPATH"
846 {
847 echo "Package: $NAME
d67004e0 848Priority: $PRIORITY
9b78cda6 849Section: other
2c085486 850Installed-Size: 42
63c71412
DK
851Maintainer: Joe Sixpack <joe@example.org>"
852 test "$arch" = 'none' || echo "Architecture: $arch"
853 echo "Version: $VERSION
854Filename: pool/main/${NAME}/${NAME}_${VERSION}_${arch}.deb"
855 test -z "$DEPENDENCIES" || echo "$DEPENDENCIES"
856 echo "Description: $(printf '%s' "$DESCRIPTION" | head -n 1)"
857 echo "Description-md5: $(printf '%s' "$DESCRIPTION" | md5sum | cut -d' ' -f 1)"
858 echo
859 } >> "${PPATH}/Packages"
10e100e5 860 done
d67004e0 861 done
63c71412
DK
862 mkdir -p "aptarchive/dists/${RELEASE}/main/source" "aptarchive/dists/${RELEASE}/main/i18n"
863 touch "aptarchive/dists/${RELEASE}/main/source/Sources"
10e100e5 864 echo "Package: $NAME
0e0d9919
DK
865Description-md5: $(printf '%s' "$DESCRIPTION" | md5sum | cut -d' ' -f 1)
866Description-en: $DESCRIPTION
63c71412 867" >> "aptarchive/dists/${RELEASE}/main/i18n/Translation-en"
10e100e5 868 done
9b78cda6
DK
869}
870
234675b7 871insertsource() {
07aca07a 872 local RELEASES="$1"
234675b7
DK
873 local NAME="$2"
874 local ARCH="$3"
875 local VERSION="$4"
876 local DEPENDENCIES="$5"
07aca07a 877 local BINARY="${6:-$NAME}"
234675b7 878 local ARCHS=""
07aca07a
DK
879 for RELEASE in $(printf '%s' "$RELEASES" | tr ',' '\n'); do
880 local SPATH="aptarchive/dists/${RELEASE}/main/source"
881 mkdir -p $SPATH
882 local FILE="${SPATH}/Sources"
883 local DSCFILE="${NAME}_${VERSION}.dsc"
884 local TARFILE="${NAME}_${VERSION}.tar.gz"
885 echo "Package: $NAME
a8275acf 886Binary: $BINARY
234675b7
DK
887Version: $VERSION
888Maintainer: Joe Sixpack <joe@example.org>
889Architecture: $ARCH" >> $FILE
07aca07a
DK
890 test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> "$FILE"
891 echo "Files:
63c71412
DK
892 $(echo -n "$DSCFILE" | md5sum | cut -d' ' -f 1) $(echo -n "$DSCFILE" | wc -c) "$DSCFILE"
893 $(echo -n "$TARFILE" | md5sum | cut -d' ' -f 1) $(echo -n "$TARFILE" | wc -c) "$TARFILE"
55ae7a51 894Checksums-Sha256:
63c71412
DK
895 $(echo -n "$DSCFILE" | sha256sum | cut -d' ' -f 1) $(echo -n "$DSCFILE" | wc -c) "$DSCFILE"
896 $(echo -n "$TARFILE" | sha256sum | cut -d' ' -f 1) $(echo -n "$TARFILE" | wc -c) "$TARFILE"
897" >> "$FILE"
07aca07a 898 done
234675b7
DK
899}
900
dfc2b1be
DK
901insertinstalledpackage() {
902 local NAME="$1"
903 local ARCH="$2"
904 local VERSION="$3"
905 local DEPENDENCIES="$4"
d67004e0 906 local PRIORITY="${5:-optional}"
d4b4e5ea 907 local STATUS="${6:-install ok installed}"
14109555 908 local DESCRIPTION="${7:-"an autogenerated dummy ${NAME}=${VERSION}/installed
18908589
DK
909 If you find such a package installed on your system,
910 something went horribly wrong! They are autogenerated
3d284148 911 und used only by testcases and serve no other purpose…"}"
18908589 912
53ea1b56
DK
913 local FILE='rootdir/var/lib/dpkg/status'
914 local INFO='rootdir/var/lib/dpkg/info'
3dcdc1f9 915 for arch in $(getarchitecturesfromcommalist "$ARCH"); do
d67004e0 916 echo "Package: $NAME
d4b4e5ea 917Status: $STATUS
d67004e0 918Priority: $PRIORITY
dfc2b1be
DK
919Section: other
920Installed-Size: 42
921Maintainer: Joe Sixpack <joe@example.org>
63c71412
DK
922Version: $VERSION" >> "$FILE"
923 test "$arch" = 'none' || echo "Architecture: $arch" >> "$FILE"
924 test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> "$FILE"
925 echo "Description: $DESCRIPTION" >> "$FILE"
926 echo >> "$FILE"
53ea1b56 927 if [ "$(dpkg-query -W --showformat='${Multi-Arch}')" = 'same' ]; then
63c71412 928 echo -n > "${INFO}/${NAME}:${arch}.list"
53ea1b56 929 else
63c71412 930 echo -n > "${INFO}/${NAME}.list"
53ea1b56 931 fi
d67004e0 932 done
dfc2b1be
DK
933}
934
935
ce9864a8 936buildaptarchivefromincoming() {
63c71412 937 msginfo "Build APT archive for ${CCMD}${0##*/}${CINFO} based on incoming packages…"
ce9864a8
DK
938 cd aptarchive
939 [ -e pool ] || ln -s ../incoming pool
940 [ -e ftparchive.conf ] || createaptftparchiveconfig
941 [ -e dists ] || buildaptftparchivedirectorystructure
b7899b00 942 msgninfo "\tGenerate Packages, Sources and Contents files… "
31be38d2 943 testsuccess aptftparchive generate ftparchive.conf
ce9864a8
DK
944 cd - > /dev/null
945 msgdone "info"
4dbfe436 946 generatereleasefiles "$@"
ce9864a8
DK
947}
948
949buildaptarchivefromfiles() {
63c71412 950 msginfo "Build APT archive for ${CCMD}${0##*/}${CINFO} based on prebuild files…"
8d041b4f
DK
951 local DIR='aptarchive'
952 if [ -d "${DIR}/dists" ]; then DIR="${DIR}/dists"; fi
953 find "$DIR" -name 'Packages' -o -name 'Sources' -o -name 'Translation-*' | while read line; do
9b78cda6 954 msgninfo "\t${line} file… "
276e51dd 955 compressfile "$line" "$1"
8d876415 956 msgdone "info"
9b78cda6 957 done
e3c62328 958 generatereleasefiles "$@"
9b78cda6
DK
959}
960
276e51dd 961compressfile() {
bdc42211 962 while read compressor extension command; do
276e51dd
DK
963 if [ "$compressor" = '.' ]; then
964 if [ -n "$2" ]; then
965 touch -d "$2" "$1"
966 fi
967 continue
968 fi
969 cat "$1" | $command > "${1}.${extension}"
970 if [ -n "$2" ]; then
971 touch -d "$2" "${1}.${extension}"
972 fi
bdc42211 973 done < "${TMPWORKINGDIRECTORY}/rootdir/etc/testcase-compressor.conf"
276e51dd
DK
974}
975
a3bbbab7 976# can be overridden by testcases for their pleasure
bf9e7447
DK
977getcodenamefromsuite() {
978 case "$1" in
979 unstable) echo 'sid';;
980 *) echo -n "$1";;
981 esac
982}
a3bbbab7 983getreleaseversionfromsuite() { true; }
718f797c 984getlabelfromsuite() { true; }
d56e2917 985getoriginfromsuite() { true; }
1dd20368 986getarchitecturesfromreleasefile() { echo "all $(getarchitectures)"; }
a3bbbab7 987
c5ede4ca
DK
988aptftparchiverelease() {
989 aptftparchive -qq release "$@" | sed -e '/0 Release$/ d' # remove the self reference
990}
9b78cda6 991generatereleasefiles() {
884a4c0a
DK
992 # $1 is the Date header and $2 is the ValidUntil header to be set
993 # both should be given in notation date/touch can understand
1dd20368
DK
994 local DATE="$1"
995 local VALIDUNTIL="$2"
9b78cda6 996 if [ -e aptarchive/dists ]; then
87d6947d 997 msgninfo "\tGenerate Release files for dists… "
9b78cda6 998 for dir in $(find ./aptarchive/dists -mindepth 1 -maxdepth 1 -type d); do
1dd20368 999 local ARCHITECTURES="$(getarchitecturesfromreleasefile "$dir")"
a3bbbab7
DK
1000 local SUITE="$(echo "$dir" | cut -d'/' -f 4)"
1001 local CODENAME="$(getcodenamefromsuite $SUITE)"
1002 local VERSION="$(getreleaseversionfromsuite $SUITE)"
718f797c 1003 local LABEL="$(getlabelfromsuite $SUITE)"
d56e2917 1004 local ORIGIN="$(getoriginfromsuite $SUITE)"
63c71412 1005 aptftparchiverelease "$dir" \
884a4c0a
DK
1006 -o APT::FTPArchive::Release::Suite="${SUITE}" \
1007 -o APT::FTPArchive::Release::Codename="${CODENAME}" \
bc7a59dd
DK
1008 -o APT::FTPArchive::Release::Architectures="${ARCHITECTURES}" \
1009 -o APT::FTPArchive::Release::Label="${LABEL}" \
1010 -o APT::FTPArchive::Release::Origin="${ORIGIN}" \
1011 -o APT::FTPArchive::Release::Version="${VERSION}" \
63c71412 1012 > "$dir/Release"
a3bbbab7 1013 if [ "$SUITE" = "experimental" -o "$SUITE" = "experimental2" ]; then
35faae11 1014 sed -i '/^Date: / a\
63c71412 1015NotAutomatic: yes' "$dir/Release"
35faae11 1016 fi
9b78cda6
DK
1017 done
1018 else
87d6947d 1019 msgninfo "\tGenerate Release files for flat… "
c5ede4ca 1020 aptftparchiverelease ./aptarchive > aptarchive/Release
8d876415 1021 fi
1dd20368 1022 if [ -n "$DATE" -a "$DATE" != "now" ]; then
fe0f7911 1023 for release in $(find ./aptarchive -name 'Release'); do
0b45b6e5 1024 sed -i "s/^Date: .*$/Date: $(date -u -d "$DATE" -R)/" "$release"
1dd20368 1025 touch -d "$DATE" "$release"
fe0f7911 1026 done
8d876415 1027 fi
1dd20368 1028 if [ -n "$VALIDUNTIL" ]; then
c5ede4ca 1029 sed -i "/^Date: / a\
0b45b6e5 1030Valid-Until: $(date -u -d "$VALIDUNTIL" -R)" $(find ./aptarchive -name 'Release')
c5ede4ca 1031 fi
b7899b00 1032 msgdone "info"
8d876415
DK
1033}
1034
b7899b00 1035setupdistsaptarchive() {
63c71412 1036 local APTARCHIVE="$(readlink -f ./aptarchive | sed 's# #%20#g')"
b7899b00
DK
1037 rm -f root/etc/apt/sources.list.d/apt-test-*-deb.list
1038 rm -f root/etc/apt/sources.list.d/apt-test-*-deb-src.list
1039 for DISTS in $(find ./aptarchive/dists/ -mindepth 1 -maxdepth 1 -type d | cut -d'/' -f 4); do
63c71412 1040 SECTIONS=$(find "./aptarchive/dists/${DISTS}/" -mindepth 1 -maxdepth 1 -type d | cut -d'/' -f 5 | tr '\n' ' ')
b7899b00 1041 msgninfo "\tadd deb and deb-src sources.list lines for ${CCMD}${DISTS} ${SECTIONS}${CINFO}… "
63c71412
DK
1042 echo "deb file://$APTARCHIVE $DISTS $SECTIONS" > "rootdir/etc/apt/sources.list.d/apt-test-${DISTS}-deb.list"
1043 echo "deb-src file://$APTARCHIVE $DISTS $SECTIONS" > "rootdir/etc/apt/sources.list.d/apt-test-${DISTS}-deb-src.list"
b7899b00
DK
1044 msgdone "info"
1045 done
1046}
1047
1048setupflataptarchive() {
63c71412
DK
1049 local APTARCHIVE="$(readlink -f ./aptarchive)"
1050 local APTARCHIVEURI="$(readlink -f ./aptarchive | sed 's# #%20#g')"
1051 if [ -f "${APTARCHIVE}/Packages" ]; then
8d876415 1052 msgninfo "\tadd deb sources.list line… "
63c71412
DK
1053 echo "deb file://$APTARCHIVEURI /" > 'rootdir/etc/apt/sources.list.d/apt-test-archive-deb.list'
1054 msgdone 'info'
8d876415 1055 else
63c71412 1056 rm -f 'rootdir/etc/apt/sources.list.d/apt-test-archive-deb.list'
8d876415 1057 fi
63c71412 1058 if [ -f "${APTARCHIVE}/Sources" ]; then
8d876415 1059 msgninfo "\tadd deb-src sources.list line… "
63c71412
DK
1060 echo "deb-src file://$APTARCHIVEURI /" > 'rootdir/etc/apt/sources.list.d/apt-test-archive-deb-src.list'
1061 msgdone 'info'
8d876415 1062 else
63c71412 1063 rm -f 'rootdir/etc/apt/sources.list.d/apt-test-archive-deb-src.list'
8d876415 1064 fi
b7899b00
DK
1065}
1066
1067setupaptarchive() {
4dbfe436
DK
1068 local NOUPDATE=0
1069 if [ "$1" = '--no-update' ]; then
1070 NOUPDATE=1
1071 shift
1072 fi
1073 buildaptarchive "$@"
b7899b00
DK
1074 if [ -e aptarchive/dists ]; then
1075 setupdistsaptarchive
1076 else
1077 setupflataptarchive
1078 fi
9d653a6d 1079 signreleasefiles 'Joe Sixpack'
4dbfe436 1080 if [ "1" != "$NOUPDATE" ]; then
5684f71f 1081 testsuccess aptget update -o Debug::pkgAcquire::Worker=true -o Debug::Acquire::gpgv=true
b2ea1a47 1082 fi
8d876415
DK
1083}
1084
f213b6ea 1085signreleasefiles() {
fb7b11eb 1086 local SIGNERS="${1:-Joe Sixpack}"
07cb47e7 1087 local REPODIR="${2:-aptarchive}"
1af227c2
DK
1088 if [ -n "$1" ]; then shift; fi
1089 if [ -n "$1" ]; then shift; fi
fb7b11eb
DK
1090 local KEY="keys/$(echo "$SIGNERS" | tr 'A-Z' 'a-z' | tr -d ' ,')"
1091 msgninfo "\tSign archive with $SIGNERS key $KEY… "
29a59c46
DK
1092 local REXKEY='keys/rexexpired'
1093 local SECEXPIREBAK="${REXKEY}.sec.bak"
1094 local PUBEXPIREBAK="${REXKEY}.pub.bak"
fb7b11eb
DK
1095 local SIGUSERS=""
1096 while [ -n "${SIGNERS%%,*}" ]; do
1097 local SIGNER="${SIGNERS%%,*}"
1098 if [ "${SIGNERS}" = "${SIGNER}" ]; then
1099 SIGNERS=""
1100 fi
1101 SIGNERS="${SIGNERS#*,}"
1102 # FIXME: This should be the full name, but we can't encode the space properly currently
1103 SIGUSERS="${SIGUSERS} -u ${SIGNER#* }"
1104 if [ "${SIGNER}" = 'Rex Expired' ]; then
1105 # the key is expired, so gpg doesn't allow to sign with and the --faked-system-time
1106 # option doesn't exist anymore (and using faketime would add a new obscure dependency)
1107 # therefore we 'temporary' make the key not expired and restore a backup after signing
1108 cp "${REXKEY}.sec" "$SECEXPIREBAK"
1109 cp "${REXKEY}.pub" "$PUBEXPIREBAK"
1110 local SECUNEXPIRED="${REXKEY}.sec.unexpired"
1111 local PUBUNEXPIRED="${REXKEY}.pub.unexpired"
1112 if [ -f "$SECUNEXPIRED" ] && [ -f "$PUBUNEXPIRED" ]; then
1113 cp "$SECUNEXPIRED" "${REXKEY}.sec"
1114 cp "$PUBUNEXPIRED" "${REXKEY}.pub"
1115 else
1116 if ! printf "expire\n1w\nsave\n" | aptkey --quiet --keyring "${REXKEY}.pub" --secret-keyring "${REXKEY}.sec" \
1117 --readonly adv --batch --yes --digest-algo "${APT_TESTS_DIGEST_ALGO:-SHA512}" \
1118 --default-key "$SIGNER" --command-fd 0 --edit-key "${SIGNER}" >setexpire.gpg 2>&1; then
1119 cat setexpire.gpg
1120 exit 1
1121 fi
1122 cp "${REXKEY}.sec" "$SECUNEXPIRED"
1123 cp "${REXKEY}.pub" "$PUBUNEXPIRED"
f1e1abd8 1124 fi
29a59c46 1125 fi
fb7b11eb
DK
1126 if [ ! -e "${KEY}.pub" ]; then
1127 local K="keys/$(echo "$SIGNER" | tr 'A-Z' 'a-z' | tr -d ' ,')"
1128 cat "${K}.pub" >> "${KEY}.new.pub"
1129 cat "${K}.sec" >> "${KEY}.new.sec"
1130 fi
1131 done
1132 if [ ! -e "${KEY}.pub" ]; then
1133 mv "${KEY}.new.pub" "${KEY}.pub"
1134 mv "${KEY}.new.sec" "${KEY}.sec"
29a59c46 1135 fi
fb7b11eb 1136 local GPG="aptkey --quiet --keyring ${KEY}.pub --secret-keyring ${KEY}.sec --readonly adv --batch --yes --digest-algo ${APT_TESTS_DIGEST_ALGO:-SHA512}"
63c71412 1137 for RELEASE in $(find "${REPODIR}/" -name Release); do
e3c62328 1138 # we might have set a specific date for the Release file, so copy it
761a5ad2
DK
1139 local DATE="$(stat --format "%y" "${RELEASE}")"
1140 if [ "$APT_DONT_SIGN" = 'Release.gpg' ]; then
1141 rm -f "${RELEASE}.gpg"
1142 else
1143 testsuccess $GPG "$@" $SIGUSERS --armor --detach-sign --sign --output "${RELEASE}.gpg" "${RELEASE}"
1144 touch -d "$DATE" "${RELEASE}.gpg"
1145 fi
1146 local INRELEASE="${RELEASE%/*}/InRelease"
1147 if [ "$APT_DONT_SIGN" = 'InRelease' ]; then
1148 rm -f "$INRELEASE"
1149 else
1150 testsuccess $GPG "$@" $SIGUSERS --clearsign --output "$INRELEASE" "$RELEASE"
1151 touch -d "$DATE" "${INRELEASE}"
1152 fi
f213b6ea 1153 done
29a59c46 1154 if [ -f "$SECEXPIREBAK" ] && [ -f "$PUBEXPIREBAK" ]; then
63c71412
DK
1155 mv -f "$SECEXPIREBAK" "${REXKEY}.sec"
1156 mv -f "$PUBEXPIREBAK" "${REXKEY}.pub"
29a59c46 1157 fi
63c71412 1158 msgdone 'info'
f213b6ea
DK
1159}
1160
8eafc759 1161redatereleasefiles() {
0b45b6e5 1162 local DATE="$(date -u -d "$1" -R)"
8eafc759 1163 for release in $(find aptarchive/ -name 'Release'); do
63c71412
DK
1164 sed -i "s/^Date: .*$/Date: ${DATE}/" "$release"
1165 touch -d "$DATE" "$release"
8eafc759
DK
1166 done
1167 signreleasefiles "${2:-Joe Sixpack}"
1168}
1169
f2c0ec8b 1170webserverconfig() {
6c0765c0 1171 local WEBSERVER="${3:-http://localhost:${APTHTTPPORT}}"
b0314abb
DK
1172 local NOCHECK=false
1173 if [ "$1" = '--no-check' ]; then
1174 NOCHECK=true
1175 shift
1176 fi
0d58c26a 1177 local DOWNLOG='rootdir/tmp/download-testfile.log'
b0314abb 1178 local STATUS='downloaded/webserverconfig.status'
0d58c26a 1179 rm -f "$STATUS" "$DOWNLOG"
6c0765c0 1180 # very very basic URI encoding
b0314abb
DK
1181 local URI
1182 if [ -n "$2" ]; then
1183 msgtest "Set webserver config option '${1}' to" "$2"
6c0765c0 1184 URI="${WEBSERVER}/_config/set/$(echo "${1}" | sed -e 's/\//%2f/g')/$(echo "${2}" | sed -e 's/\//%2f/g')"
b0314abb
DK
1185 else
1186 msgtest 'Clear webserver config option' "${1}"
6c0765c0 1187 URI="${WEBSERVER}/_config/clear/$(echo "${1}" | sed -e 's/\//%2f/g')"
b0314abb
DK
1188 fi
1189 if downloadfile "$URI" "$STATUS" > "$DOWNLOG"; then
f2c0ec8b
DK
1190 msgpass
1191 else
68042532
DK
1192 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/webserverconfig.output"
1193 cat "$DOWNLOG" "$STATUS" >"$OUTPUT" 2>&1 || true
1194 msgfailoutput '' "$OUTPUT"
f2c0ec8b 1195 fi
b0314abb 1196 $NOCHECK || testwebserverlaststatuscode '200'
f2c0ec8b
DK
1197}
1198
fd46d305 1199rewritesourceslist() {
63c71412 1200 local APTARCHIVE="file://$(readlink -f "${TMPWORKINGDIRECTORY}/aptarchive" | sed 's# #%20#g')"
af9e40c9 1201 local APTARCHIVE2="copy://$(readlink -f "${TMPWORKINGDIRECTORY}/aptarchive" | sed 's# #%20#g')"
fd46d305 1202 for LIST in $(find rootdir/etc/apt/sources.list.d/ -name 'apt-test-*.list'); do
af9e40c9 1203 sed -i $LIST -e "s#$APTARCHIVE#${1}#" -e "s#$APTARCHIVE2#${1}#" \
28b2efcb
DK
1204 -e "s#http://[^@]*@\?localhost:${APTHTTPPORT}/\?#${1}#" \
1205 -e "s#https://[^@]*@\?localhost:${APTHTTPSPORT}/\?#${1}#"
fd46d305
DK
1206 done
1207}
1208
5572f6bd
MV
1209# wait for up to 10s for a pid file to appear to avoid possible race
1210# when a helper is started and dosn't write the PID quick enough
1211waitforpidfile() {
1212 local PIDFILE="$1"
1213 for i in $(seq 10); do
1214 if test -s "$PIDFILE"; then
1215 return 0
1216 fi
1217 sleep 1
1218 done
1219 msgdie "waiting for $PIDFILE failed"
1220 return 1
1221}
1222
f213b6ea 1223changetowebserver() {
6c0765c0 1224 local REWRITE='no'
23af9f40 1225 if [ "$1" != '--no-rewrite' ]; then
6c0765c0 1226 REWRITE='yes'
23af9f40
DK
1227 else
1228 shift
1229 fi
63c71412 1230 if test -x "${APTWEBSERVERBINDIR}/aptwebserver"; then
fbd29dd6 1231 cd aptarchive
a0db467c 1232 local LOG="webserver.log"
6c0765c0 1233 if ! aptwebserver --port 0 -o aptwebserver::fork=1 -o aptwebserver::portfile='aptwebserver.port' "$@" >$LOG 2>&1 ; then
3abb6a6a 1234 cat "$LOG"
bee0670b
DK
1235 false
1236 fi
6c0765c0 1237 waitforpidfile aptwebserver.pid
e3c62328
DK
1238 local PID="$(cat aptwebserver.pid)"
1239 if [ -z "$PID" ]; then
1240 msgdie 'Could not fork aptwebserver successfully'
1241 fi
1242 addtrap "kill $PID;"
6c0765c0
DK
1243 waitforpidfile aptwebserver.port
1244 APTHTTPPORT="$(cat aptwebserver.port)"
1245 if [ -z "$APTHTTPPORT" ]; then
1246 msgdie 'Could not get port for aptwebserver successfully'
1247 fi
fbd29dd6 1248 cd - > /dev/null
c5bcc607 1249 else
3d284148 1250 msgdie 'You have to build apt from source to have test/interactive-helper/aptwebserver available for tests requiring a webserver'
f213b6ea 1251 fi
6c0765c0
DK
1252 if [ "$REWRTE" != 'yes' ]; then
1253 rewritesourceslist "http://localhost:${APTHTTPPORT}/"
1254 fi
fd46d305
DK
1255}
1256
1257changetohttpswebserver() {
e75e5879 1258 if ! command -v stunnel4 >/dev/null 2>&1; then
fd46d305
DK
1259 msgdie 'You need to install stunnel4 for https testcases'
1260 fi
1261 if [ ! -e "${TMPWORKINGDIRECTORY}/aptarchive/aptwebserver.pid" ]; then
dc95fee1 1262 changetowebserver --no-rewrite "$@"
fd46d305
DK
1263 fi
1264 echo "pid = ${TMPWORKINGDIRECTORY}/aptarchive/stunnel.pid
68ba0b7f 1265cert = ${TMPWORKINGDIRECTORY}/rootdir/etc/webserver.pem
23af9f40 1266output = /dev/null
fd46d305
DK
1267
1268[https]
6c0765c0
DK
1269accept = 0
1270connect = $APTHTTPPORT
63c71412 1271" > "${TMPWORKINGDIRECTORY}/stunnel.conf"
fd46d305 1272 stunnel4 "${TMPWORKINGDIRECTORY}/stunnel.conf"
5572f6bd 1273 waitforpidfile "${TMPWORKINGDIRECTORY}/aptarchive/stunnel.pid"
63c71412 1274 local PID="$(cat "${TMPWORKINGDIRECTORY}/aptarchive/stunnel.pid")"
5572f6bd
MV
1275 if [ -z "$PID" ]; then
1276 msgdie 'Could not fork stunnel4 successfully'
1277 fi
fd46d305 1278 addtrap 'prefix' "kill ${PID};"
6970f6e6 1279 APTHTTPSPORT="$(lsof -i -n | awk "/^stunnel4 / && \$2 == \"${PID}\" {print \$9; exit; }" | cut -d':' -f 2)"
6c0765c0
DK
1280 webserverconfig 'aptwebserver::port::https' "$APTHTTPSPORT" "https://localhost:${APTHTTPSPORT}"
1281 rewritesourceslist "https://localhost:${APTHTTPSPORT}/"
f213b6ea
DK
1282}
1283
c45233ea
DK
1284changetocdrom() {
1285 mkdir -p rootdir/media/cdrom/.disk
1286 local CD="$(readlink -f rootdir/media/cdrom)"
63c71412
DK
1287 cat > rootdir/etc/apt/apt.conf.d/00cdrom <<EOF
1288acquire::cdrom::mount "${CD}";
1289acquire::cdrom::"${CD}/"::mount "mv ${CD}-unmounted ${CD}";
1290acquire::cdrom::"${CD}/"::umount "mv ${CD} ${CD}-unmounted";
1291acquire::cdrom::autodetect 0;
1292EOF
1293 echo -n "$1" > "${CD}/.disk/info"
c45233ea
DK
1294 if [ ! -d aptarchive/dists ]; then
1295 msgdie 'Flat file archive cdroms can not be created currently'
1296 return 1
1297 fi
a0975c8d 1298 mv aptarchive/dists "$CD"
63c71412 1299 ln -s "$(readlink -f ./incoming)" "$CD/pool"
c45233ea 1300 find rootdir/etc/apt/sources.list.d/ -name 'apt-test-*.list' -delete
a0975c8d
DK
1301 # start with an unmounted disk
1302 mv "${CD}" "${CD}-unmounted"
1303 # we don't want the disk to be modifiable
bc8f83a5 1304 addtrap 'prefix' "chmod -f -R +w '$(escape_shell "$PWD/rootdir/media/cdrom/dists/")' '$(escape_shell "$PWD/rootdir/media/cdrom-unmounted/dists/")' || true;"
b0314abb 1305 chmod -R 555 rootdir/media/cdrom-unmounted/dists
c45233ea
DK
1306}
1307
fd46d305 1308downloadfile() {
ed793a19 1309 local PROTO="${1%%:*}"
27925d82 1310 if ! apthelper -o Debug::Acquire::${PROTO}=1 -o Debug::pkgAcquire::Worker=1 \
dcbb364f 1311 download-file "$1" "$2" "$3" 2>&1 ; then
27925d82
DK
1312 return 1
1313 fi
fd46d305 1314 # only if the file exists the download was successful
b0314abb 1315 if [ -r "$2" ]; then
fd46d305
DK
1316 return 0
1317 else
1318 return 1
1319 fi
1320}
1321
f213b6ea 1322checkdiff() {
03aa0847 1323 local DIFFTEXT="$(command diff -u "$@" 2>&1 | sed -e '/^---/ d' -e '/^+++/ d' -e '/^@@/ d')"
8d876415 1324 if [ -n "$DIFFTEXT" ]; then
0d58c26a
DK
1325 echo >&2
1326 echo >&2 "$DIFFTEXT"
8d876415
DK
1327 return 1
1328 else
1329 return 0
1330 fi
1331}
1332
22ac12b2
DK
1333testoutputequal() {
1334 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testoutputequal.output"
1335 local COMPAREFILE="$1"
1336 shift
63c71412 1337 if "$@" 2>&1 | checkdiff "$COMPAREFILE" - >"$OUTPUT" 2>&1; then
22ac12b2
DK
1338 msgpass
1339 else
1340 echo "=== content of file we compared with (${COMPAREFILE}) ===" >>"${OUTPUT}"
1341 cat "$COMPAREFILE" >>"${OUTPUT}"
1342 msgfailoutput '' "$OUTPUT" "$@"
1343 fi
1344}
1345
75954ae2 1346testfileequal() {
1501a2c9 1347 msggroup 'testfileequal'
e6a12ff7
DK
1348 local MSG='Test for correctness of file'
1349 if [ "$1" = '--nomsg' ]; then
1350 MSG=''
1351 shift
1352 fi
75954ae2
DK
1353 local FILE="$1"
1354 shift
e6a12ff7
DK
1355 if [ -n "$MSG" ]; then
1356 msgtest "$MSG" "$FILE"
1357 fi
68042532 1358 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testfileequal.output"
75954ae2 1359 if [ -z "$*" ]; then
22ac12b2 1360 testoutputequal "$FILE" echo -n ''
75954ae2 1361 else
22ac12b2 1362 testoutputequal "$FILE" echo "$*"
75954ae2 1363 fi
9beb11aa 1364 msggroup
75954ae2
DK
1365}
1366
b855a400 1367testempty() {
1501a2c9 1368 msggroup 'testempty'
a66e1837
DK
1369 if [ "$1" = '--nomsg' ]; then
1370 shift
1371 else
1372 msgtest "Test for no output of" "$*"
1373 fi
859093da 1374 local COMPAREFILE="${TMPWORKINGDIRECTORY}/rootdir/tmp/testempty.comparefile"
a66e1837 1375 if "$@" >"$COMPAREFILE" 2>&1 && test ! -s "$COMPAREFILE"; then
859093da
DK
1376 msgpass
1377 else
22ac12b2 1378 msgfailoutput '' "$COMPAREFILE" "$@"
859093da 1379 fi
ab25bf1f 1380 aptautotest 'testempty' "$@"
9beb11aa 1381 msggroup
b855a400 1382}
63c71412
DK
1383testnotempty() {
1384 msggroup 'testnotempty'
1385 msgtest "Test for some output of" "$*"
1386 local COMPAREFILE="${TMPWORKINGDIRECTORY}/rootdir/tmp/testnotempty.comparefile"
1387 if ("$@" >"$COMPAREFILE" 2>&1 || true) && test -s "$COMPAREFILE"; then
1388 msgpass
1389 else
1390 msgfailoutput '' "$COMPAREFILE" "$@"
1391 fi
1392 aptautotest 'testnotempty' "$@"
1393 msggroup
1394}
b855a400 1395
f74a6fa1 1396testequal() {
1501a2c9 1397 msggroup 'testequal'
f74a6fa1
DK
1398 local MSG='Test of equality of'
1399 if [ "$1" = '--nomsg' ]; then
1400 MSG=''
1401 shift
1402 fi
1403
03938280 1404 local COMPAREFILE="${TMPWORKINGDIRECTORY}/rootdir/tmp/testequal.comparefile"
63c71412 1405 echo "$1" > "$COMPAREFILE"
8d876415 1406 shift
d2d68aaf 1407
f74a6fa1
DK
1408 if [ -n "$MSG" ]; then
1409 msgtest "$MSG" "$*"
1410 fi
22ac12b2 1411 testoutputequal "$COMPAREFILE" "$@"
ab25bf1f 1412 aptautotest 'testequal' "$@"
9beb11aa 1413 msggroup
8d876415
DK
1414}
1415
685625bd 1416testequalor2() {
1501a2c9 1417 msggroup 'testequalor2'
03938280
DK
1418 local COMPAREFILE1="${TMPWORKINGDIRECTORY}/rootdir/tmp/testequalor2.comparefile1"
1419 local COMPAREFILE2="${TMPWORKINGDIRECTORY}/rootdir/tmp/testequalor2.comparefile2"
1420 local COMPAREAGAINST="${TMPWORKINGDIRECTORY}/rootdir/tmp/testequalor2.compareagainst"
63c71412
DK
1421 echo "$1" > "$COMPAREFILE1"
1422 echo "$2" > "$COMPAREFILE2"
685625bd
DK
1423 shift 2
1424 msgtest "Test for equality OR of" "$*"
63c71412
DK
1425 "$@" >"$COMPAREAGAINST" 2>&1 || true
1426 if checkdiff "$COMPAREFILE1" "$COMPAREAGAINST" >/dev/null 2>&1 || \
1427 checkdiff "$COMPAREFILE2" "$COMPAREAGAINST" >/dev/null 2>&1
0d58c26a 1428 then
0caa5a4c
DK
1429 msgpass
1430 else
68042532
DK
1431 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testequal.output"
1432 echo -n "\n${CINFO}Diff against OR 1${CNORMAL}" >"$OUTPUT" 2>&1
1433 checkdiff "$COMPAREFILE1" "$COMPAREAGAINST" >"$OUTPUT" 2>&1 || true
1434 echo -n "${CINFO}Diff against OR 2${CNORMAL}" >"$OUTPUT" 2>&1
1435 checkdiff "$COMPAREFILE2" "$COMPAREAGAINST" >"$OUTPUT" 2>&1 || true
1436 msgfailoutput '' "$OUTPUT"
0caa5a4c 1437 fi
ab25bf1f 1438 aptautotest 'testequalor2' "$@"
9beb11aa 1439 msggroup
685625bd
DK
1440}
1441
8d876415 1442testshowvirtual() {
1501a2c9 1443 msggroup 'testshowvirtual'
edc0ef10 1444 local VIRTUAL="N: Can't select versions from package '$1' as it is purely virtual"
8d876415
DK
1445 local PACKAGE="$1"
1446 shift
1447 while [ -n "$1" ]; do
1448 VIRTUAL="${VIRTUAL}
edc0ef10 1449N: Can't select versions from package '$1' as it is purely virtual"
8d876415
DK
1450 PACKAGE="${PACKAGE} $1"
1451 shift
1452 done
1453 msgtest "Test for virtual packages" "apt-cache show $PACKAGE"
1454 VIRTUAL="${VIRTUAL}
4bec02c2 1455N: No packages found"
03938280 1456 local COMPAREFILE="${TMPWORKINGDIRECTORY}/rootdir/tmp/testshowvirtual.comparefile"
ea65d079 1457 local ARCH="$(getarchitecture 'native')"
68042532
DK
1458 echo "$VIRTUAL" | sed -e "s/:$ARCH//" -e 's/:all//' >"$COMPAREFILE"
1459 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testshowvirtual.output"
87d6947d 1460 testoutputequal "$COMPAREFILE" aptcache show "$PACKAGE"
9beb11aa 1461 msggroup
8d876415
DK
1462}
1463
1464testnopackage() {
1501a2c9 1465 msggroup 'testnopackage'
8d876415 1466 msgtest "Test for non-existent packages" "apt-cache show $*"
846856f4 1467 local SHOWPKG="$(aptcache show "$@" 2>&1 | grep '^Package: ')"
8d876415 1468 if [ -n "$SHOWPKG" ]; then
68042532
DK
1469 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testnopackage.output"
1470 echo "$SHOWPKG" >"$OUTPUT"
1471 msgfailoutput '' "$OUTPUT"
0d58c26a
DK
1472 else
1473 msgpass
8d876415 1474 fi
9beb11aa 1475 msggroup
8d876415 1476}
bd4a8f51
DK
1477testnosrcpackage() {
1478 msggroup 'testnosrcpackage'
1479 msgtest "Test for non-existent source packages" "apt-cache showsrc $*"
1480 local SHOWPKG="$(aptcache showsrc "$@" 2>&1 | grep '^Package: ')"
1481 if [ -n "$SHOWPKG" ]; then
1482 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testnosrcpackage.output"
1483 echo "$SHOWPKG" >"$OUTPUT"
1484 msgfailoutput '' "$OUTPUT"
1485 else
1486 msgpass
1487 fi
1488 msggroup
1489}
01a6e24c 1490
ecb777dd 1491testdpkgstatus() {
1501a2c9 1492 msggroup 'testdpkgstatus'
ecb777dd
DK
1493 local STATE="$1"
1494 local NR="$2"
1495 shift 2
1496 msgtest "Test that $NR package(s) are in state $STATE with" "dpkg -l $*"
1497 local PKGS="$(dpkg -l "$@" 2>/dev/null | grep "^${STATE}" | wc -l)"
1498 if [ "$PKGS" != $NR ]; then
68042532
DK
1499 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testnopackage.output"
1500 echo "$PKGS" >"$OUTPUT"
1501 dpkg -l "$@" | grep '^[a-z]' >"$OUTPUT" >&2 || true
1502 msgfailoutput '' "$OUTPUT"
0d58c26a
DK
1503 else
1504 msgpass
01a6e24c 1505 fi
9beb11aa 1506 msggroup
01a6e24c
DK
1507}
1508
ecb777dd 1509testdpkginstalled() {
1501a2c9 1510 msggroup 'testdpkginstalled'
ecb777dd 1511 testdpkgstatus 'ii' "$#" "$@"
9beb11aa 1512 msggroup
ecb777dd
DK
1513}
1514
5cf733e1 1515testdpkgnotinstalled() {
1501a2c9 1516 msggroup 'testdpkgnotinstalled'
ecb777dd 1517 testdpkgstatus 'ii' '0' "$@"
9beb11aa 1518 msggroup
01a6e24c 1519}
ec7f904e
DK
1520
1521testmarkedauto() {
1501a2c9 1522 msggroup 'testmarkedauto'
03938280 1523 local COMPAREFILE="${TMPWORKINGDIRECTORY}/rootdir/tmp/testmarkedauto.comparefile"
ec7f904e
DK
1524 if [ -n "$1" ]; then
1525 msgtest 'Test for correctly marked as auto-installed' "$*"
63c71412 1526 while [ -n "$1" ]; do echo "$1"; shift; done | sort > "$COMPAREFILE"
ec7f904e
DK
1527 else
1528 msgtest 'Test for correctly marked as auto-installed' 'no package'
63c71412 1529 echo -n > "$COMPAREFILE"
ec7f904e 1530 fi
22ac12b2 1531 testoutputequal "$COMPAREFILE" aptmark showauto
9beb11aa 1532 msggroup
ec7f904e 1533}
7c2cc4a7 1534testmarkedmanual() {
1501a2c9 1535 msggroup 'testmarkedmanual'
7c2cc4a7
DK
1536 local COMPAREFILE="${TMPWORKINGDIRECTORY}/rootdir/tmp/testmarkedmanual.comparefile"
1537 if [ -n "$1" ]; then
1538 msgtest 'Test for correctly marked as manually installed' "$*"
63c71412 1539 while [ -n "$1" ]; do echo "$1"; shift; done | sort > "$COMPAREFILE"
7c2cc4a7
DK
1540 else
1541 msgtest 'Test for correctly marked as manually installed' 'no package'
63c71412 1542 echo -n > "$COMPAREFILE"
7c2cc4a7 1543 fi
22ac12b2 1544 testoutputequal "$COMPAREFILE" aptmark showmanual
9beb11aa 1545 msggroup
7c2cc4a7 1546}
89a1aa5d 1547
742f67ea
DK
1548catfile() {
1549 if [ "${1##*.}" = 'deb' ]; then
1550 stat >&2 "$1" || true
1551 file >&2 "$1" || true
1552 else
1553 cat >&2 "$1" || true
1554 fi
1555}
e52aad52 1556msgfailoutput() {
1501a2c9 1557 msgreportheader 'msgfailoutput'
e52aad52
DK
1558 local MSG="$1"
1559 local OUTPUT="$2"
1560 shift 2
b4f91d4d
DK
1561 local CMD="$1"
1562 if [ "$1" = 'grep' -o "$1" = 'tail' -o "$1" = 'head' ]; then
68042532 1563 echo >&2
e52aad52
DK
1564 while [ -n "$2" ]; do shift; done
1565 echo "#### Complete file: $1 ####"
742f67ea 1566 catfile "$1"
b4f91d4d 1567 echo "#### $CMD output ####"
e52aad52 1568 elif [ "$1" = 'test' ]; then
68042532 1569 echo >&2
e52aad52
DK
1570 # doesn't support ! or non-file flags
1571 msgfailoutputstatfile() {
1572 local FILEFLAGS='^-[bcdefgGhkLOprsStuwx]$'
1573 if expr match "$1" "$FILEFLAGS" >/dev/null; then
1574 echo "#### stat(2) of file: $2 ####"
1575 stat "$2" || true
dffc17ba
DK
1576 if test -d "$2"; then
1577 echo "#### The directory contains: $2 ####"
1578 ls >&2 "$2" || true
1579 elif test -e "$2"; then
3196dae8 1580 echo "#### Complete file: $2 ####"
742f67ea 1581 catfile "$2"
3196dae8 1582 fi
e52aad52
DK
1583 fi
1584 }
1585 msgfailoutputstatfile "$2" "$3"
1586 while [ -n "$5" ] && [ "$4" = '-o' -o "$4" = '-a' ]; do
1587 shift 3
1588 msgfailoutputstatfile "$2" "$3"
1589 done
1590 echo '#### test output ####'
6fc2e030
DK
1591 elif [ "$1" = 'cmp' ]; then
1592 echo >&2
1593 while [ -n "$2" ]; do
1594 echo "#### Complete file: $2 ####"
742f67ea 1595 catfile "$2"
6fc2e030
DK
1596 shift
1597 done
1598 echo '#### cmp output ####'
e52aad52 1599 fi
742f67ea 1600 catfile "$OUTPUT"
e52aad52
DK
1601 msgfail "$MSG"
1602}
1603
671a55ba
DK
1604testsuccesswithglobalerror() {
1605 local TYPE="$1"
1606 local ERRORS="$2"
1607 shift 2
1608 msggroup "$TYPE"
0440d936
DK
1609 if [ "$1" = '--nomsg' ]; then
1610 shift
1611 else
1612 msgtest 'Test for successful execution of' "$*"
1613 fi
671a55ba 1614 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/${TYPE}.output"
63c71412 1615 if "$@" >"${OUTPUT}" 2>&1; then
4fa34122 1616 if expr match "$1" '^apt.*' >/dev/null; then
e52aad52
DK
1617 if grep -q -E ' runtime error: ' "$OUTPUT"; then
1618 msgfailoutput 'compiler detected undefined behavior' "$OUTPUT" "$@"
671a55ba 1619 elif grep -E "^[${ERRORS}]: " "$OUTPUT" > "${TMPWORKINGDIRECTORY}/rootdir/tmp/checkforwarnings.output" 2>&1; then
3261271e
DK
1620 if [ "$IGNORE_PTY_NOT_MOUNTED" = '1' ]; then
1621 if echo 'E: Can not write log (Is /dev/pts mounted?) - posix_openpt (2: No such file or directory)' \
1622 | cmp - "${TMPWORKINGDIRECTORY}/rootdir/tmp/checkforwarnings.output" >/dev/null 2>&1; then
1623 msgpass
1624 else
1625 msgfailoutput 'successful run, but output contains warnings/errors' "$OUTPUT" "$@"
1626 fi
1627 else
1628 msgfailoutput 'successful run, but output contains warnings/errors' "$OUTPUT" "$@"
1629 fi
671a55ba
DK
1630 elif [ "$TYPE" = 'testsuccesswithnotice' ]; then
1631 if grep -q -E "^N: " "$OUTPUT"; then
1632 msgpass
1633 else
1634 msgfailoutput 'successful run, but output had no notices' "$OUTPUT" "$@"
1635 fi
4fa34122
DK
1636 else
1637 msgpass
1638 fi
1639 else
1640 msgpass
1641 fi
1642 else
1643 local EXITCODE=$?
e52aad52 1644 msgfailoutput "exitcode $EXITCODE" "$OUTPUT" "$@"
4fa34122 1645 fi
671a55ba 1646 aptautotest "$TYPE" "$@"
9beb11aa 1647 msggroup
4fa34122 1648}
671a55ba
DK
1649testsuccesswithnotice() {
1650 testsuccesswithglobalerror 'testsuccesswithnotice' 'WE' "$@"
1651}
1652testsuccess() {
1653 testsuccesswithglobalerror 'testsuccess' 'NWE' "$@"
1654}
4fa34122 1655testwarning() {
1501a2c9 1656 msggroup 'testwarning'
4fa34122
DK
1657 if [ "$1" = '--nomsg' ]; then
1658 shift
1659 else
1660 msgtest 'Test for successful execution with warnings of' "$*"
1661 fi
25b86db1 1662 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testwarning.output"
63c71412 1663 if "$@" >"${OUTPUT}" 2>&1; then
1df24acf 1664 if expr match "$1" '^apt.*' >/dev/null; then
e52aad52
DK
1665 if grep -q -E ' runtime error: ' "$OUTPUT"; then
1666 msgfailoutput 'compiler detected undefined behavior' "$OUTPUT" "$@"
1667 elif grep -q -E '^E: ' "$OUTPUT"; then
1668 msgfailoutput 'successful run, but output contains errors' "$OUTPUT" "$@"
4fa34122 1669 elif ! grep -q -E '^W: ' "$OUTPUT"; then
e52aad52 1670 msgfailoutput 'successful run, but output contains no warnings' "$OUTPUT" "$@"
1df24acf
DK
1671 else
1672 msgpass
1673 fi
1674 else
1675 msgpass
1676 fi
0440d936 1677 else
07cb47e7 1678 local EXITCODE=$?
68042532 1679 msgfailoutput "exitcode $EXITCODE" "$OUTPUT" "$@"
0440d936 1680 fi
4fa34122 1681 aptautotest 'testwarning' "$@"
9beb11aa 1682 msggroup
0440d936 1683}
0440d936 1684testfailure() {
1501a2c9 1685 msggroup 'testfailure'
0440d936
DK
1686 if [ "$1" = '--nomsg' ]; then
1687 shift
1688 else
889b0072 1689 msgtest 'Test for failure in execution of' "$*"
0440d936 1690 fi
03938280 1691 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailure.output"
63c71412 1692 if "$@" >"${OUTPUT}" 2>&1; then
07cb47e7 1693 local EXITCODE=$?
e52aad52 1694 msgfailoutput "exitcode $EXITCODE" "$OUTPUT" "$@"
0440d936 1695 else
1df24acf
DK
1696 local EXITCODE=$?
1697 if expr match "$1" '^apt.*' >/dev/null; then
b0d40854 1698 if [ "$1" = 'aptkey' ]; then
2fac0dd5
DK
1699 if grep -q " Can't check signature:
1700 BAD signature from
1701 signature could not be verified" "$OUTPUT"; then
b0d40854
DK
1702 msgpass
1703 else
1704 msgfailoutput "run failed with exitcode ${EXITCODE}, but no signature error" "$OUTPUT" "$@"
1705 fi
1df24acf 1706 else
b0d40854
DK
1707 if grep -q -E ' runtime error: ' "$OUTPUT"; then
1708 msgfailoutput 'compiler detected undefined behavior' "$OUTPUT" "$@"
1709 elif grep -q -E '==ERROR' "$OUTPUT"; then
1710 msgfailoutput 'compiler sanitizers reported errors' "$OUTPUT" "$@"
1711 elif ! grep -q -E '^E: ' "$OUTPUT"; then
1712 msgfailoutput "run failed with exitcode ${EXITCODE}, but with no errors" "$OUTPUT" "$@"
1713 else
1714 msgpass
1715 fi
1df24acf
DK
1716 fi
1717 else
1718 msgpass
1719 fi
0440d936 1720 fi
ab25bf1f 1721 aptautotest 'testfailure' "$@"
9beb11aa 1722 msggroup
0440d936
DK
1723}
1724
7414af7f
DK
1725testreturnstateequal() {
1726 local STATE="$1"
671a55ba
DK
1727 if [ "$STATE" = 'testsuccesswithglobalerror' ]; then
1728 local STATE="$2"
1729 local TYPE="$3"
7414af7f 1730 shift 3
671a55ba
DK
1731 msggroup "${STATE}equal"
1732 if [ "$1" != '--nomsg' ]; then
1733 local CMP="$1"
1734 shift
1735 testsuccesswithglobalerror "$STATE" "$TYPE" "$@"
1736 testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/${STATE}.output" "$CMP"
1737 else
1738 local CMP="$2"
1739 shift 2
1740 testsuccesswithglobalerror "$STATE" "$TYPE" "$@"
1741 testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/${STATE}.output" "$CMP"
1742 fi
1743 else
1744 msggroup "${STATE}equal"
1745 if [ "$2" != '--nomsg' ]; then
1746 local CMP="$2"
1747 shift 2
1748 "$STATE" "$@"
1749 testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/${STATE}.output" "$CMP"
1750 else
1751 local CMP="$3"
1752 shift 3
1753 "$STATE" --nomsg "$@"
1754 testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/${STATE}.output" "$CMP"
1755 fi
7414af7f 1756 fi
9beb11aa 1757 msggroup
25b86db1 1758}
7414af7f 1759testsuccessequal() {
671a55ba
DK
1760 # we compare output, so we know perfectly well about N:
1761 testreturnstateequal 'testsuccesswithglobalerror' 'testsuccess' 'WE' "$@"
7414af7f 1762}
25b86db1 1763testwarningequal() {
7414af7f 1764 testreturnstateequal 'testwarning' "$@"
25b86db1
DK
1765}
1766testfailureequal() {
7414af7f 1767 testreturnstateequal 'testfailure' "$@"
25b86db1
DK
1768}
1769
27925d82 1770testfailuremsg() {
1501a2c9 1771 msggroup 'testfailuremsg'
27925d82
DK
1772 local CMP="$1"
1773 shift
1774 testfailure "$@"
1775 msgtest 'Check that the output of the previous failed command has expected' 'failures and warnings'
68042532 1776 local COMPAREFILE="${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailuremsg.comparefile"
002b1bc4 1777 grep '^\(W\|E\|N\):' "${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailure.output" > "$COMPAREFILE" 2>&1 || true
22ac12b2 1778 testoutputequal "$COMPAREFILE" echo "$CMP"
9beb11aa 1779 msggroup
27925d82 1780}
f18f2338
DK
1781testwarningmsg() {
1782 msggroup 'testwarningmsg'
1783 local CMP="$1"
1784 shift
1785 testwarning "$@"
1786 msgtest 'Check that the output of the previous warned command has expected' 'warnings'
1787 local COMPAREFILE="${TMPWORKINGDIRECTORY}/rootdir/tmp/testwarningmsg.comparefile"
002b1bc4 1788 grep '^\(W\|E\|N\):' "${TMPWORKINGDIRECTORY}/rootdir/tmp/testwarning.output" > "$COMPAREFILE" 2>&1 || true
f18f2338
DK
1789 testoutputequal "$COMPAREFILE" echo "$CMP"
1790 msggroup
1791}
25b86db1 1792
de81b2e2 1793testfilestats() {
1501a2c9 1794 msggroup 'testfilestats'
de81b2e2
DK
1795 msgtest "Test that file $1 has $2 $3" "$4"
1796 if [ "$4" "$3" "$(stat --format "$2" "$1")" ]; then
5684f71f
DK
1797 msgpass
1798 else
68042532
DK
1799 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testfilestats.output"
1800 {
1801 ls -ld "$1" || true
1802 echo -n "stat(1) reports for $2: "
1803 stat --format "$2" "$1" || true
1804 } >"$OUTPUT" 2>&1
1805 msgfailoutput '' "$OUTPUT"
5684f71f 1806 fi
9beb11aa 1807 msggroup
5684f71f 1808}
de81b2e2 1809testaccessrights() {
1501a2c9 1810 msggroup 'testaccessrights'
de81b2e2 1811 testfilestats "$1" '%a' '=' "$2"
9beb11aa 1812 msggroup
de81b2e2 1813}
5684f71f 1814
0d58c26a 1815testwebserverlaststatuscode() {
1501a2c9 1816 msggroup 'testwebserverlaststatuscode'
0d58c26a 1817 local DOWNLOG='rootdir/tmp/webserverstatus-testfile.log'
03aa0847 1818 local STATUS='downloaded/webserverstatus-statusfile.log'
0d58c26a
DK
1819 rm -f "$DOWNLOG" "$STATUS"
1820 msgtest 'Test last status code from the webserver was' "$1"
6c0765c0 1821 if downloadfile "http://localhost:${APTHTTPPORT}/_config/find/aptwebserver::last-status-code" "$STATUS" > "$DOWNLOG" && [ "$(cat "$STATUS")" = "$1" ]; then
0d58c26a
DK
1822 msgpass
1823 else
68042532
DK
1824 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testwebserverlaststatuscode.output"
1825 {
1826 if [ -n "$2" ]; then
1827 shift
1828 echo >&2 '#### Additionally provided output files contain:'
1829 cat >&2 "$@"
1830 fi
1831 echo >&2 '#### Download log of the status code:'
1832 cat >&2 "$DOWNLOG"
1833 } >"$OUTPUT" 2>&1
1834 msgfailoutput "Status was $(cat "$STATUS")" "$OUTPUT"
0d58c26a 1835 fi
9beb11aa 1836 msggroup
0d58c26a
DK
1837}
1838
785cb6fc
DK
1839createlistofkeys() {
1840 local OUTPUT="$1"
1841 shift
1842 while [ -n "$1" ]; do
eb5113c4
JAK
1843 # gpg 2.1.something starts printing [SC] at some point
1844 if grep -q ' rsa2048/' "$OUTPUT" && grep -qF '[SC]' "$OUTPUT"; then
1845 case "$1" in
1846 *Joe*|*Sixpack*) echo 'pub rsa2048/DBAC8DAE 2010-08-18 [SC]';;
1847 *Rex*|*Expired*) echo 'pub rsa2048/27CE74F9 2013-07-12 [SC] [expired: 2013-07-13]';;
1848 *Marvin*|*Paranoid*) echo 'pub rsa2048/528144E2 2011-01-16 [SC]';;
1849 oldarchive) echo 'pub rsa1024/F68C85A3 2013-12-19 [SC]';;
1850 newarchive) echo 'pub rsa2048/DBAC8DAE 2010-08-18 [SC]';;
1851 *) echo 'UNKNOWN KEY';;
1852 esac
785cb6fc 1853 # gpg 2.1 has a slightly different output format
eb5113c4 1854 elif grep -q ' rsa2048/' "$OUTPUT"; then
785cb6fc
DK
1855 case "$1" in
1856 *Joe*|*Sixpack*) echo 'pub rsa2048/DBAC8DAE 2010-08-18';;
1857 *Rex*|*Expired*) echo 'pub rsa2048/27CE74F9 2013-07-12 [expired: 2013-07-13]';;
1858 *Marvin*|*Paranoid*) echo 'pub rsa2048/528144E2 2011-01-16';;
1859 oldarchive) echo 'pub rsa1024/F68C85A3 2013-12-19';;
1860 newarchive) echo 'pub rsa2048/DBAC8DAE 2010-08-18';;
1861 *) echo 'UNKNOWN KEY';;
1862 esac
1863 else
1864 case "$1" in
1865 *Joe*|*Sixpack*) echo 'pub 2048R/DBAC8DAE 2010-08-18';;
1866 *Rex*|*Expired*) echo 'pub 2048R/27CE74F9 2013-07-12 [expired: 2013-07-13]';;
1867 *Marvin*|*Paranoid*) echo 'pub 2048R/528144E2 2011-01-16';;
1868 oldarchive) echo 'pub 1024R/F68C85A3 2013-12-19';;
1869 newarchive) echo 'pub 2048R/DBAC8DAE 2010-08-18';;
1870 *) echo 'UNKNOWN KEY';;
1871 esac
1872 fi
1873 shift
1874 done
1875}
1876testaptkeys() {
1877 local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/aptkeylist.output"
1878 if ! aptkey list | grep '^pub' > "$OUTPUT"; then
1879 echo -n > "$OUTPUT"
1880 fi
1881 testfileequal "$OUTPUT" "$(createlistofkeys "$OUTPUT" "$@")"
1882}
1883
89a1aa5d
DK
1884pause() {
1885 echo "STOPPED execution. Press enter to continue"
1886 local IGNORE
1887 read IGNORE
1888}
ab25bf1f 1889
34651385
DK
1890logcurrentarchivedirectory() {
1891 find "${TMPWORKINGDIRECTORY}/aptarchive/dists" -type f | while read line; do
1892 stat --format '%U:%G:%a:%n' "$line"
1893 done | sort > "${TMPWORKINGDIRECTORY}/rootdir/var/log/aptgetupdate.before.lst"
1894}
846bc058 1895listcurrentlistsdirectory() {
ba6b79bd
DK
1896 {
1897 find rootdir/var/lib/apt/lists -maxdepth 1 -type d | while read line; do
1898 stat --format '%U:%G:%a:%n' "$line"
1899 done
1900 find rootdir/var/lib/apt/lists -maxdepth 1 \! -type d | while read line; do
1901 stat --format '%U:%G:%a:%s:%y:%n' "$line"
1902 done
1903 } | sort
846bc058 1904}
912a6131 1905forallsupportedcompressors() {
b2fd8524 1906 rm -f "${TMPWORKINGDIRECTORY}/rootdir/etc/apt/apt.conf.d/00force-compressor"
912a6131 1907 for COMP in $(aptconfig dump 'APT::Compressor' --format '%f%n' | cut -d':' -f 5 | uniq); do
0179cfa8 1908 if [ -z "$COMP" -o "$COMP" = '.' ]; then continue; fi
912a6131
DK
1909 "$@" "$COMP"
1910 done
1911}
846bc058 1912
3a8776a3 1913### convenience hacks ###
8fe964f1
DK
1914mkdir() {
1915 # creating some directories by hand is a tedious task, so make it look simple
6aef1942
DK
1916 local PARAMS="$*"
1917 if [ "$PARAMS" != "${PARAMS#*rootdir/var/lib/apt/lists}" ]; then
8fe964f1
DK
1918 # only the last directory created by mkdir is effected by the -m !
1919 command mkdir -m 755 -p "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt"
1920 command mkdir -m 755 -p "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists"
1921 command mkdir -m 700 -p "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial"
1922 touch "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/lock"
1923 if [ "$(id -u)" = '0' ]; then
1924 chown _apt:root "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial"
1925 fi
1926 else
1927 command mkdir "$@"
1928 fi
1929}
1930
ab25bf1f
DK
1931### The following tests are run by most test methods automatically to check
1932### general things about commands executed without writing the test every time.
1933
1934aptautotest() {
c1e202d2 1935 if [ $# -lt 3 ]; then return; fi
ab25bf1f
DK
1936 local TESTCALL="$1"
1937 local CMD="$2"
1938 local FIRSTOPT="$3"
c1e202d2
DK
1939 shift 2
1940 for i in "$@"; do
1941 if ! expr match "$i" '^-' >/dev/null 2>&1; then
1942 FIRSTOPT="$i"
1943 break
1944 fi
1945 done
1946 shift
896f0ae8 1947 local AUTOTEST="aptautotest_$(echo "${CMD##*/}_${FIRSTOPT}" | tr -d -c 'A-za-z0-9')"
ab25bf1f 1948 if command -v $AUTOTEST >/dev/null; then
ab25bf1f
DK
1949 # save and restore the *.output files from other tests
1950 # as we might otherwise override them in these automatic tests
63c71412
DK
1951 rm -rf "${TMPWORKINGDIRECTORY}/rootdir/tmp-before"
1952 mv "${TMPWORKINGDIRECTORY}/rootdir/tmp" "${TMPWORKINGDIRECTORY}/rootdir/tmp-before"
1953 mkdir "${TMPWORKINGDIRECTORY}/rootdir/tmp"
ab25bf1f 1954 $AUTOTEST "$TESTCALL" "$@"
63c71412
DK
1955 rm -rf "${TMPWORKINGDIRECTORY}/rootdir/tmp-aptautotest"
1956 mv "${TMPWORKINGDIRECTORY}/rootdir/tmp" "${TMPWORKINGDIRECTORY}/rootdir/tmp-aptautotest"
1957 mv "${TMPWORKINGDIRECTORY}/rootdir/tmp-before" "${TMPWORKINGDIRECTORY}/rootdir/tmp"
ab25bf1f
DK
1958 fi
1959}
1960
1961aptautotest_aptget_update() {
59148d96
DK
1962 local TESTCALL="$1"
1963 while [ -n "$2" ]; do
1964 if [ "$2" = '--print-uris' ]; then return; fi # simulation mode
1965 shift
1966 done
ab25bf1f 1967 if ! test -d "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists"; then return; fi
4bb006d1
DK
1968 testfilestats "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:755"
1969 testfilestats "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:755"
ab25bf1f 1970 # all copied files are properly chmodded
63c71412
DK
1971 local backupIFS="$IFS"
1972 IFS="$(printf "\n\b")"
146f7715 1973 for file in $(find "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" -type f ! -name 'lock'); do
4bb006d1 1974 testfilestats "$file" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644"
ab25bf1f 1975 done
63c71412 1976 IFS="$backupIFS"
59148d96 1977 if [ "$TESTCALL" = 'testsuccess' ]; then
146f7715
DK
1978 # failure cases can retain partial files and such
1979 testempty find "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial" -mindepth 1 ! \( -name 'lock' -o -name '*.FAILED' \)
1980 fi
34651385
DK
1981 if [ -s "${TMPWORKINGDIRECTORY}/rootdir/var/log/aptgetupdate.before.lst" ]; then
1982 testfileequal "${TMPWORKINGDIRECTORY}/rootdir/var/log/aptgetupdate.before.lst" \
1983 "$(find "${TMPWORKINGDIRECTORY}/aptarchive/dists" -type f | while read line; do stat --format '%U:%G:%a:%n' "$line"; done | sort)"
1984 fi
ab25bf1f
DK
1985}
1986aptautotest_apt_update() { aptautotest_aptget_update "$@"; }
d84da499 1987aptautotest_aptcdrom_add() { aptautotest_aptget_update "$@"; }
016bea82
DK
1988
1989testaptautotestnodpkgwarning() {
1990 local TESTCALL="$1"
1991 while [ -n "$2" ]; do
6bf93605
DK
1992 if expr match "$2" '^-[a-z]*s' >/dev/null 2>&1; then return; fi # simulation mode
1993 if expr match "$2" '^-dy\?' >/dev/null 2>&1; then return; fi # download-only mode
016bea82
DK
1994 shift
1995 done
1996 testfailure grep '^dpkg: warning:.*ignor.*' "${TMPWORKINGDIRECTORY}/rootdir/tmp-before/${TESTCALL}.output"
1997}
1998
1999aptautotest_aptget_install() { testaptautotestnodpkgwarning "$@"; }
2000aptautotest_aptget_remove() { testaptautotestnodpkgwarning "$@"; }
2001aptautotest_aptget_purge() { testaptautotestnodpkgwarning "$@"; }
2002aptautotest_apt_install() { testaptautotestnodpkgwarning "$@"; }
2003aptautotest_apt_remove() { testaptautotestnodpkgwarning "$@"; }
2004aptautotest_apt_purge() { testaptautotestnodpkgwarning "$@"; }
e5c3f3cc
DK
2005
2006testaptmarknodefaultsections() {
2007 testfailure grep '^Auto-Installed: 0$' "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/extended_states"
2008}
2009aptautotest_aptmark_auto() { testaptmarknodefaultsections "$@"; }
2010aptautotest_aptmark_manual() { testaptmarknodefaultsections "$@"; }
2011aptautotest_aptget_markauto() { testaptmarknodefaultsections "$@"; }
2012aptautotest_aptget_markmanual() { testaptmarknodefaultsections "$@"; }