X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/5abee4863220c2d9b135dc832b33c8680e5ba12e..9f3713fc037ca363b514c8d8f7cbb65fdab2e8b1:/test/integration/framework diff --git a/test/integration/framework b/test/integration/framework index 2ea1844f0..7dd7c20a7 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1,5 +1,7 @@ #!/bin/sh -- # no runable script, just for vi +EXIT_CODE=0 + # we all like colorful messages if expr match "$(readlink -f /proc/$$/fd/1)" '/dev/pts/[0-9]\+' > /dev/null && \ expr match "$(readlink -f /proc/$$/fd/2)" '/dev/pts/[0-9]\+' > /dev/null; then @@ -25,10 +27,22 @@ msgnwarn() { echo -n "${CWARNING}W: $1${CNORMAL}" >&2; } msgnmsg() { echo -n "${CMSG}$1${CNORMAL}" >&2; } msgninfo() { echo -n "${CINFO}I: $1${CNORMAL}" >&2; } msgndebug() { echo -n "${CDEBUG}D: $1${CNORMAL}" >&2; } -msgtest() { echo -n "${CINFO}$1 ${CCMD}$(echo "$2" | sed -e 's/^aptc/apt-c/' -e 's/^aptg/apt-g/' -e 's/^aptf/apt-f/')${CINFO} …${CNORMAL} " >&2; } +msgtest() { + while [ -n "$1" ]; do + echo -n "${CINFO}$1${CCMD} " >&2; + echo -n "$(echo "$2" | sed -e 's/^aptc/apt-c/' -e 's/^aptg/apt-g/' -e 's/^aptf/apt-f/')${CINFO} " >&2; + shift + if [ -n "$1" ]; then shift; else break; fi + done + echo -n "…${CNORMAL} " >&2; +} msgpass() { echo "${CPASS}PASS${CNORMAL}" >&2; } msgskip() { echo "${CWARNING}SKIP${CNORMAL}" >&2; } -msgfail() { echo "${CFAIL}FAIL${CNORMAL}" >&2; } +msgfail() { + if [ $# -gt 0 ]; then echo "${CFAIL}FAIL: $*${CNORMAL}" >&2; + else echo "${CFAIL}FAIL${CNORMAL}" >&2; fi + EXIT_CODE=$((EXIT_CODE+1)); +} # enable / disable Debugging MSGLEVEL=${MSGLEVEL:-3} @@ -46,9 +60,9 @@ if [ $MSGLEVEL -le 2 ]; then msgpass() { echo -n " ${CPASS}P${CNORMAL}" >&2; } msgskip() { echo -n " ${CWARNING}S${CNORMAL}" >&2; } if [ -n "$CFAIL" ]; then - msgfail() { echo -n " ${CFAIL}FAIL${CNORMAL}" >&2; } + msgfail() { echo -n " ${CFAIL}FAIL${CNORMAL}" >&2; EXIT_CODE=$((EXIT_CODE+1)); } else - msgfail() { echo -n " ###FAILED###" >&2; } + msgfail() { echo -n " ###FAILED###" >&2; EXIT_CODE=$((EXIT_CODE+1)); } fi fi if [ $MSGLEVEL -le 3 ]; then @@ -83,6 +97,7 @@ runapt() { } aptconfig() { runapt apt-config $*; } aptcache() { runapt apt-cache $*; } +aptcdrom() { runapt apt-cdrom $*; } aptget() { runapt apt-get $*; } aptftparchive() { runapt apt-ftparchive $*; } aptkey() { runapt apt-key $*; } @@ -99,45 +114,58 @@ aptitude() { LD_LIBRARY_PATH=${BUILDDIRECTORY} $(which aptitude) $* fi } +gdb() { + echo "gdb: run »$*«" + APT_CONFIG=aptconfig.conf LD_LIBRARY_PATH=${BUILDDIRECTORY} $(which gdb) ${BUILDDIRECTORY}/$1 +} +http() { + LD_LIBRARY_PATH=${BUILDDIRECTORY} ${BUILDDIRECTORY}/methods/http +} + +exitwithstatus() { + # error if we about to overflow, but ... + # "255 failures ought to be enough for everybody" + if [ $EXIT_CODE -gt 255 ]; then + msgdie "Total failure count $EXIT_CODE too big" + fi + exit $((EXIT_CODE <= 255 ? EXIT_CODE : 255)); +} addtrap() { - CURRENTTRAP="$CURRENTTRAP $1" - trap "$CURRENTTRAP exit;" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM + if [ "$1" = 'prefix' ]; then + CURRENTTRAP="$2 $CURRENTTRAP" + else + CURRENTTRAP="$CURRENTTRAP $1" + fi + trap "$CURRENTTRAP exitwithstatus;" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM } setupenvironment() { TMPWORKINGDIRECTORY=$(mktemp -d) - local TESTDIR=$(readlink -f $(dirname $0)) + TESTDIRECTORY=$(readlink -f $(dirname $0)) msgninfo "Preparing environment for ${CCMD}$(basename $0)${CINFO} in ${TMPWORKINGDIRECTORY}… " - BUILDDIRECTORY="${TESTDIR}/../../build/bin" + BUILDDIRECTORY="${TESTDIRECTORY}/../../build/bin" test -x "${BUILDDIRECTORY}/apt-get" || msgdie "You need to build tree first" - local OLDWORKINGDIRECTORY=$(pwd) - addtrap "cd /; rm -rf $TMPWORKINGDIRECTORY; cd $OLDWORKINGDIRECTORY;" + addtrap "cd /; rm -rf $TMPWORKINGDIRECTORY;" cd $TMPWORKINGDIRECTORY mkdir rootdir aptarchive keys cd rootdir mkdir -p etc/apt/apt.conf.d etc/apt/sources.list.d etc/apt/trusted.gpg.d etc/apt/preferences.d mkdir -p var/cache var/lib var/log mkdir -p var/lib/dpkg/info var/lib/dpkg/updates var/lib/dpkg/triggers - local STATUSFILE=$(echo "$(basename $0)" | sed -e 's/^test-/status-/' -e 's/^skip-/status-/') - if [ -f "${TESTDIR}/${STATUSFILE}" ]; then - cp "${TESTDIR}/${STATUSFILE}" var/lib/dpkg/status - else - touch var/lib/dpkg/status - fi touch var/lib/dpkg/available mkdir -p usr/lib/apt ln -s ${BUILDDIRECTORY}/methods usr/lib/apt/methods cd .. local PACKAGESFILE=$(echo "$(basename $0)" | sed -e 's/^test-/Packages-/' -e 's/^skip-/Packages-/') - if [ -f "${TESTDIR}/${PACKAGESFILE}" ]; then - cp "${TESTDIR}/${PACKAGESFILE}" aptarchive/Packages + if [ -f "${TESTDIRECTORY}/${PACKAGESFILE}" ]; then + cp "${TESTDIRECTORY}/${PACKAGESFILE}" aptarchive/Packages fi local SOURCESSFILE=$(echo "$(basename $0)" | sed -e 's/^test-/Sources-/' -e 's/^skip-/Sources-/') - if [ -f "${TESTDIR}/${SOURCESSFILE}" ]; then - cp "${TESTDIR}/${SOURCESSFILE}" aptarchive/Sources + if [ -f "${TESTDIRECTORY}/${SOURCESSFILE}" ]; then + cp "${TESTDIRECTORY}/${SOURCESSFILE}" aptarchive/Sources fi - cp $(find $TESTDIR -name '*.pub' -o -name '*.sec') keys/ + cp $(find $TESTDIRECTORY -name '*.pub' -o -name '*.sec') keys/ ln -s ${TMPWORKINGDIRECTORY}/keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg echo "Dir \"${TMPWORKINGDIRECTORY}/rootdir\";" > aptconfig.conf echo "Dir::state::status \"${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status\";" >> aptconfig.conf @@ -149,7 +177,9 @@ setupenvironment() { echo "DPKG::options:: \"--root=${TMPWORKINGDIRECTORY}/rootdir\";" >> aptconfig.conf echo "DPKG::options:: \"--force-not-root\";" >> aptconfig.conf echo "DPKG::options:: \"--force-bad-path\";" >> aptconfig.conf - echo "DPKG::options:: \"--force-architecture\";" >> aptconfig.conf # Added to test multiarch before dpkg is ready for it… + if ! $(which dpkg) --assert-multi-arch 2>&1 > /dev/null; then + echo "DPKG::options:: \"--force-architecture\";" >> aptconfig.conf # Added to test multiarch before dpkg is ready for it… + fi echo "DPKG::options:: \"--log=${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log\";" >> aptconfig.conf echo 'quiet::NoUpdate "true";' >> aptconfig.conf export LC_ALL=C @@ -163,13 +193,17 @@ getarchitecture() { if [ -n "$ARCH" ]; then echo $ARCH else - dpkg-architecture -qDEB_BUILD_ARCH + dpkg --print-architecture fi else echo $1 fi } +getarchitectures() { + echo "$(aptconfig dump | grep APT::Architecture | cut -d'"' -f 2 | sed '/^$/ d' | sort | uniq | tr '\n' ' ')" +} + configarchitecture() { local CONFFILE=rootdir/etc/apt/apt.conf.d/01multiarch.conf rm -f $CONFFILE @@ -179,6 +213,32 @@ configarchitecture() { echo "APT::Architectures:: \"$(getarchitecture $1)\";" >> $CONFFILE shift done + configdpkg +} + +configdpkg() { + if [ ! -e rootdir/var/lib/dpkg/status ]; then + local STATUSFILE=$(echo "$(basename $0)" | sed -e 's/^test-/status-/' -e 's/^skip-/status-/') + if [ -f "${TESTDIRECTORY}/${STATUSFILE}" ]; then + cp "${TESTDIRECTORY}/${STATUSFILE}" rootdir/var/lib/dpkg/status + else + echo -n > rootdir/var/lib/dpkg/status + fi + fi + if $(which dpkg) --assert-multi-arch 2>&1 > /dev/null; then + local ARCHS="$(getarchitectures)" + if echo "$ARCHS" | grep -E -q '[^ ]+ [^ ]+'; then + DPKGARCH="$(dpkg --print-architecture)" + for ARCH in ${ARCHS}; do + if [ "${ARCH}" != "${DPKGARCH}" ]; then dpkg --add-architecture ${ARCH}; fi + done + if [ "0" = "$(dpkg -l dpkg 2> /dev/null | grep '^i' | wc -l)" ]; then + # dpkg doesn't really check the version as long as it is fully installed, + # but just to be sure we choose one above the required version + insertinstalledpackage 'dpkg' "all" '1.16.2+fake' + fi + fi + fi } setupsimplenativepackage() { @@ -266,27 +326,38 @@ echo '$NAME says \"Hello!\"'" > ${BUILDDIR}/${NAME} Section: $SECTION Priority: $PRIORITY Maintainer: Joe Sixpack -Standards-Version: 3.9.1 +Standards-Version: 3.9.3" > ${BUILDDIR}/debian/control + local BUILDDEPS="$(echo "$DEPENDENCIES" | grep '^Build-')" + test -z "$BUILDDEPS" || echo "$BUILDDEPS" >> ${BUILDDIR}/debian/control + echo " +Package: $NAME" >> ${BUILDDIR}/debian/control -Package: $NAME" > ${BUILDDIR}/debian/control if [ "$ARCH" = 'all' ]; then echo "Architecture: all" >> ${BUILDDIR}/debian/control else echo "Architecture: any" >> ${BUILDDIR}/debian/control fi - test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> ${BUILDDIR}/debian/control + local DEPS="$(echo "$DEPENDENCIES" | grep -v '^Build-')" + test -z "$DEPS" || echo "$DEPS" >> ${BUILDDIR}/debian/control if [ -z "$DESCRIPTION" ]; then echo "Description: an autogenerated dummy ${NAME}=${VERSION}/${RELEASE} If you find such a package installed on your system, YOU did something horribly wrong! They are autogenerated und used only by testcases for APT and surf no other propose…" >> ${BUILDDIR}/debian/control else - echo "Description: $DESCRIPTION" >> ${BUILDIR}/debian/control + echo "Description: $DESCRIPTION" >> ${BUILDDIR}/debian/control fi + echo '3.0 (native)' > ${BUILDDIR}/debian/source/format - local SRCS="$( (cd ${BUILDDIR}/..; dpkg-source -b ${NAME}-${VERSION} 2>&1) | grep '^dpkg-source: info: building' | grep -o '[a-z0-9._+~-]*$')" - for SRC in $SRCS; do + (cd ${BUILDDIR}/..; dpkg-source -b ${NAME}-${VERSION} 2>&1) | sed -n 's#^dpkg-source: info: building [^ ]\+ in ##p' \ + | while read SRC; do echo "pool/${SRC}" >> ${BUILDDIR}/../${RELEASE}.${DISTSECTION}.srclist +# if expr match "${SRC}" '.*\.dsc' >/dev/null 2>&1; then +# gpg --yes --no-default-keyring --secret-keyring ./keys/joesixpack.sec \ +# --keyring ./keys/joesixpack.pub --default-key 'Joe Sixpack' \ +# --clearsign -o "${BUILDDIR}/../${SRC}.sign" "${BUILDDIR}/../$SRC" +# mv "${BUILDDIR}/../${SRC}.sign" "${BUILDDIR}/../$SRC" +# fi done for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do @@ -343,7 +414,7 @@ createaptftparchiveconfig() { local ARCHS="$(find pool/ -name '*.deb' | grep -oE '_[a-z0-9-]+\.deb$' | sort | uniq | sed -e '/^_all.deb$/ d' -e 's#^_\([a-z0-9-]*\)\.deb$#\1#' | tr '\n' ' ')" if [ -z "$ARCHS" ]; then # the pool is empty, so we will operate on faked packages - let us use the configured archs - ARCHS="$(aptconfig dump | grep APT::Architecture | cut -d'"' -f 2 | sed '/^$/ d' | sort | uniq | tr '\n' ' ')" + ARCHS="$(getarchitectures)" fi echo -n 'Dir { ArchiveDir "' >> ftparchive.conf @@ -422,10 +493,11 @@ insertpackage() { local VERSION="$4" local DEPENDENCIES="$5" local PRIORITY="${6:-optional}" + local DESCRIPTION="${7}" local ARCHS="" for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do - if [ "$arch" = "all" ]; then - ARCHS="$(aptconfig dump | grep APT::Architecture | cut -d'"' -f 2 | sed '/^$/ d' | sort | uniq | tr '\n' ' ')" + if [ "$arch" = 'all' -o "$arch" = 'none' ]; then + ARCHS="$(getarchitectures)" else ARCHS="$arch" fi @@ -438,16 +510,21 @@ insertpackage() { Priority: $PRIORITY Section: other Installed-Size: 42 -Maintainer: Joe Sixpack -Architecture: $arch -Version: $VERSION +Maintainer: Joe Sixpack " >> $FILE + test "$arch" = 'none' || echo "Architecture: $arch" >> $FILE + echo "Version: $VERSION Filename: pool/main/${NAME}/${NAME}_${VERSION}_${arch}.deb" >> $FILE test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE - echo "Description: an autogenerated dummy ${NAME}=${VERSION}/${RELEASE} + echo -n 'Description: ' >> $FILE + if [ -z "$DESCRIPTION" ]; then + echo "an autogenerated dummy ${NAME}=${VERSION}/${RELEASE} If you find such a package installed on your system, YOU did something horribly wrong! They are autogenerated - und used only by testcases for APT and surf no other propose… -" >> $FILE + und used only by testcases for APT and surf no other propose…" >> $FILE + else + echo "$DESCRIPTION" >> $FILE + fi + echo >> $FILE done done } @@ -470,7 +547,8 @@ Architecture: $ARCH" >> $FILE test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE echo "Files: d41d8cd98f00b204e9800998ecf8427e 0 ${NAME}_${VERSION}.dsc - d41d8cd98f00b204e9800998ecf8427e 0 ${NAME}_${VERSION}.tar.gz" >> $FILE + d41d8cd98f00b204e9800998ecf8427e 0 ${NAME}_${VERSION}.tar.gz +" >> $FILE } insertinstalledpackage() { @@ -479,22 +557,29 @@ insertinstalledpackage() { local VERSION="$3" local DEPENDENCIES="$4" local PRIORITY="${5:-optional}" - local FILE="rootdir/var/lib/dpkg/status" + local STATUS="${6:-install ok installed}" + local FILE='rootdir/var/lib/dpkg/status' + local INFO='rootdir/var/lib/dpkg/info' for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do echo "Package: $NAME -Status: install ok installed +Status: $STATUS Priority: $PRIORITY Section: other Installed-Size: 42 Maintainer: Joe Sixpack -Architecture: $arch Version: $VERSION" >> $FILE + test "$arch" = 'none' || echo "Architecture: $arch" >> $FILE test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE echo "Description: an autogenerated dummy ${NAME}=${VERSION}/installed If you find such a package installed on your system, YOU did something horribly wrong! They are autogenerated und used only by testcases for APT and surf no other propose… " >> $FILE + if [ "$(dpkg-query -W --showformat='${Multi-Arch}')" = 'same' ]; then + echo -n > ${INFO}/${NAME}:${arch}.list + else + echo -n > ${INFO}/${NAME}.list + fi done } @@ -518,11 +603,14 @@ buildaptarchivefromfiles() { msgninfo "\t${line} file… " cat ${line} | gzip > ${line}.gz cat ${line} | bzip2 > ${line}.bz2 - cat ${line} | lzma > ${line}.lzma + cat ${line} | xz --format=lzma > ${line}.lzma cat ${line} | xz > ${line}.xz + if [ -n "$1" ]; then + touch -d "$1" ${line}.gz ${line}.bz2 ${line}.lzma ${line}.xz + fi msgdone "info" done - generatereleasefiles + generatereleasefiles "$@" } # can be overridden by testcases for their pleasure @@ -535,9 +623,6 @@ generatereleasefiles() { # both should be given in notation date/touch can understand msgninfo "\tGenerate Release files… " if [ -e aptarchive/dists ]; then - for dir in $(find ./aptarchive/dists -mindepth 3 -maxdepth 3 -type d -name 'i18n'); do - aptftparchive -qq release $dir -o APT::FTPArchive::Release::Patterns::='Translation-*' > $dir/Index - done for dir in $(find ./aptarchive/dists -mindepth 1 -maxdepth 1 -type d); do local SUITE="$(echo "$dir" | cut -d'/' -f 4)" local CODENAME="$(getcodenamefromsuite $SUITE)" @@ -617,9 +702,11 @@ setupaptarchive() { setupflataptarchive fi signreleasefiles - msgninfo "\tSync APT's cache with the archive… " - aptget update -qq - msgdone "info" + if [ "$1" != '--no-update' ]; then + msgninfo "\tSync APT's cache with the archive… " + aptget update -qq + msgdone "info" + fi } signreleasefiles() { @@ -635,18 +722,33 @@ signreleasefiles() { done for RELEASE in $(find aptarchive/ -name Release); do gpg --yes --no-default-keyring $SECKEYS $PUBKEYS --default-key "$SIGNER" -abs -o ${RELEASE}.gpg ${RELEASE} - gpg --yes --no-default-keyring $SECKEYS $PUBKEYS --default-key "$SIGNER" --clearsign -o "$(echo "${RELEASE}" | sed 's#/Release$#/InRelease#')" $RELEASE + local INRELEASE="$(echo "${RELEASE}" | sed 's#/Release$#/InRelease#')" + gpg --yes --no-default-keyring $SECKEYS $PUBKEYS --default-key "$SIGNER" --clearsign -o $INRELEASE $RELEASE + # we might have set a specific date for the Release file, so copy it + touch -d "$(stat --format "%y" ${RELEASE})" ${RELEASE}.gpg ${INRELEASE} done msgdone "info" } changetowebserver() { - if which weborf > /dev/null; then - weborf -xb aptarchive/ 2>&1 > /dev/null & + local LOG='/dev/null' + if test -x ${BUILDDIRECTORY}/aptwebserver; then + cd aptarchive + LD_LIBRARY_PATH=${BUILDDIRECTORY} ${BUILDDIRECTORY}/aptwebserver -o aptwebserver::fork=1 "$@" >$LOG 2>&1 + local PID="$(cat aptwebserver.pid)" + if [ -z "$PID" ]; then + msgdie 'Could not fork aptwebserver successfully' + fi + addtrap "kill $PID;" + cd - > /dev/null + elif [ $# -gt 0 ]; then + msgdie 'Need the aptwebserver when passing arguments for the webserver' + elif which weborf > /dev/null; then + weborf -xb aptarchive/ >$LOG 2>&1 & addtrap "kill $!;" elif which gatling > /dev/null; then cd aptarchive - gatling -p 8080 -F -S 2>&1 > /dev/null & + gatling -p 8080 -F -S >$LOG 2>&1 & addtrap "kill $!;" cd - > /dev/null elif which lighttpd > /dev/null; then @@ -654,11 +756,10 @@ changetowebserver() { server.port = 8080 server.stat-cache-engine = \"disable\"" > lighttpd.conf lighttpd -t -f lighttpd.conf >/dev/null || msgdie 'Can not change to webserver: our lighttpd config is invalid' - lighttpd -D -f lighttpd.conf 2>/dev/null >/dev/null & + lighttpd -D -f lighttpd.conf >$LOG 2>&1 & addtrap "kill $!;" else - msgdie 'You have to install weborf or lighttpd first' - return 1 + msgdie 'You have to build aptwerbserver or install a webserver' fi local APTARCHIVE="file://$(readlink -f ./aptarchive)" for LIST in $(find rootdir/etc/apt/sources.list.d/ -name 'apt-test-*.list'); do @@ -667,6 +768,21 @@ server.stat-cache-engine = \"disable\"" > lighttpd.conf return 0 } +changetocdrom() { + mkdir -p rootdir/media/cdrom/.disk + local CD="$(readlink -f rootdir/media/cdrom)" + echo "acquire::cdrom::mount \"${CD}\";" > rootdir/etc/apt/apt.conf.d/00cdrom + echo 'acquire::cdrom::autodetect 0;' >> rootdir/etc/apt/apt.conf.d/00cdrom + echo -n "$1" > ${CD}/.disk/info + if [ ! -d aptarchive/dists ]; then + msgdie 'Flat file archive cdroms can not be created currently' + return 1 + fi + mv aptarchive/dists $CD + ln -s "$(readlink -f ./incoming)" $CD/pool + find rootdir/etc/apt/sources.list.d/ -name 'apt-test-*.list' -delete +} + checkdiff() { local DIFFTEXT="$($(which diff) -u $* | sed -e '/^---/ d' -e '/^+++/ d' -e '/^@@/ d')" if [ -n "$DIFFTEXT" ]; then @@ -689,6 +805,11 @@ testfileequal() { fi } +testempty() { + msgtest "Test for no output of" "$*" + test -z "$($* 2>&1)" && msgpass || msgfail +} + testequal() { local COMPAREFILE=$(mktemp) addtrap "rm $COMPAREFILE;" @@ -749,7 +870,7 @@ testnopackage() { testdpkginstalled() { msgtest "Test for correctly installed package(s) with" "dpkg -l $*" - local PKGS="$(dpkg -l $* | grep '^i' | wc -l)" + local PKGS="$(dpkg -l $* 2>/dev/null | grep '^i' | wc -l)" if [ "$PKGS" != $# ]; then echo $PKGS dpkg -l $* | grep '^[a-z]'