]> git.saurik.com Git - apt.git/blobdiff - test/integration/framework
test: Substitute GNU commands for other commands where available
[apt.git] / test / integration / framework
index 8ca878148743c2add20ca3850165ad084cb42979..25cabc9f8a954b363ef4abbd690c5219e87aaa87 100644 (file)
@@ -31,7 +31,6 @@ if [ "${MSGCOLOR:-YES}" = 'YES' ]; then
        fi
 fi
 
-
 if [ "$MSGCOLOR" != 'NO' ]; then
        CERROR="\033[1;31m" # red
        CWARNING="\033[1;33m" # yellow
@@ -180,7 +179,7 @@ aptconfig() { runapt apt-config "$@"; }
 aptcache() { runapt apt-cache "$@"; }
 aptcdrom() { runapt apt-cdrom "$@"; }
 aptget() { runapt apt-get "$@"; }
-aptftparchive() { runapt apt-ftparchive "$@"; }
+aptftparchive() { runapt "${APTFTPARCHIVEBINDIR}/apt-ftparchive" "$@"; }
 aptkey() { runapt apt-key "$@"; }
 aptmark() { runapt apt-mark "$@"; }
 aptsortpkgs() { runapt apt-sortpkgs "$@"; }
@@ -216,13 +215,13 @@ gdb() {
        if [ "${CMD##*/}" = "$CMD" ]; then
                CMD="${BUILDDIRECTORY}/${CMD}"
        fi
-       runapt command gdb --quiet -ex run "$CMD" --args "$CMD" "$@"
+       runapt command gdb --quiet -ex "directory '$SOURCEDIRECTORY'" -ex run "$CMD" --args "$CMD" "$@"
 }
 lastmodification() {
-       date -u -d "@$(stat -c '%Y' "${TMPWORKINGDIRECTORY}/$1")" '+%a, %d %b %Y %H:%M:%S GMT'
+       date -u -d "@$(stat -c '%Y' "${TMPWORKINGDIRECTORY}/$1")" -R
 }
 releasefiledate() {
-       grep "^${2:-Date}:" "$1" | cut -d' ' -f 2- | sed -e 's#UTC#GMT#'
+       grep "^${2:-Date}:" "$1" | cut -d' ' -f 2-
 }
 
 exitwithstatus() {
@@ -257,9 +256,32 @@ escape_shell() {
     echo "$@" | sed -e "s#'#'\"'\"'#g"
 }
 
+find_project_binary_dir() {
+       local TESTDIRECTORY="$(readlink -f "$(dirname $0)")"
+       if [ -z "$PROJECT_BINARY_DIR" ]; then
+               PROJECT_BINARY_DIR=
+               for dir in ${TESTDIRECTORY}/../../ ${TESTDIRECTORY}/../../*; do
+                       test -e "$dir/CMakeCache.txt"  || continue
+                       if [ -z "$PROJECT_BINARY_DIR" ] ||
+                          [ "$dir/CMakeCache.txt" -nt "$PROJECT_BINARY_DIR/CMakeCache.txt" ]; then
+                               PROJECT_BINARY_DIR="$dir"
+                       fi
+               done
+               if [ -z "$PROJECT_BINARY_DIR" ]; then
+                       echo "Cannot find build directory, you might want to set PROJECT_BINARY_DIR" >&2
+                       exit 1
+               fi
+               export PROJECT_BINARY_DIR
+       fi
+}
 setupenvironment() {
+       # Next check needs a gnu stat, let's figure that out early.
+       stat=stat
+       if command -v gnustat >/dev/null 2>&1; then
+               stat=gnustat
+       fi
        # privilege dropping and testing doesn't work if /tmp isn't world-writeable (as e.g. with libpam-tmpdir)
-       if [ -n "$TMPDIR" ] && [ "$(id -u)" = '0' ] && [ "$(stat --format '%a' "$TMPDIR")" != '1777' ]; then
+       if [ -n "$TMPDIR" ] && [ "$(id -u)" = '0' ] && [ "$($stat --format '%a' "$TMPDIR")" != '1777' ]; then
                unset TMPDIR
        fi
        TMPWORKINGDIRECTORY="$(mktemp -d)"
@@ -272,6 +294,18 @@ setupenvironment() {
        fi
        msgninfo "Preparing environment for ${0##*/} in ${TMPWORKINGDIRECTORY}…"
 
+       # Setup coreutils on BSD systems
+       mkdir "${TMPWORKINGDIRECTORY}/bin"
+       for prefix in gnu g; do
+                       for command in stat touch sed cp tr sha1sum sha256sum md5sum sha512sum grep date wc chmod head readlink tar expr base64; do
+                                       if command -v $prefix$command 2>/dev/null >/dev/null; then
+                                                       [ -e "${TMPWORKINGDIRECTORY}/bin/$command" ] || ln -sf $(command -v $prefix$command)  "${TMPWORKINGDIRECTORY}/bin/$command"
+                                       fi
+                       done
+       done
+       export PATH="${TMPWORKINGDIRECTORY}/bin/:$PATH"
+
+
        mkdir -m 700 "${TMPWORKINGDIRECTORY}/downloaded"
        if [ "$(id -u)" = '0' ]; then
                # relax permissions so that running as root with user switching works
@@ -281,16 +315,19 @@ setupenvironment() {
        fi
 
        TESTDIRECTORY="$(readlink -f "$(dirname $0)")"
+       # Find the newest build directory (sets PROJECT_BINARY_DIR)
+       find_project_binary_dir
         # allow overriding the default BUILDDIR location
        SOURCEDIRECTORY="${APT_INTEGRATION_TESTS_SOURCE_DIR:-"${TESTDIRECTORY}/../../"}"
-       BUILDDIRECTORY="${APT_INTEGRATION_TESTS_BUILD_DIR:-"${TESTDIRECTORY}/../../build/bin"}"
-       LIBRARYPATH="${APT_INTEGRATION_TESTS_LIBRARY_PATH:-"${BUILDDIRECTORY}"}"
-        METHODSDIR="${APT_INTEGRATION_TESTS_METHODS_DIR:-"${BUILDDIRECTORY}/methods"}"
+       BUILDDIRECTORY="${APT_INTEGRATION_TESTS_BUILD_DIR:-"${PROJECT_BINARY_DIR}/cmdline"}"
+       LIBRARYPATH="${APT_INTEGRATION_TESTS_LIBRARY_PATH:-"${BUILDDIRECTORY}/../apt-pkg"}"
+        METHODSDIR="${APT_INTEGRATION_TESTS_METHODS_DIR:-"${BUILDDIRECTORY}/../methods"}"
         APTHELPERBINDIR="${APT_INTEGRATION_TESTS_LIBEXEC_DIR:-"${BUILDDIRECTORY}"}"
-        APTWEBSERVERBINDIR="${APT_INTEGRATION_TESTS_WEBSERVER_BIN_DIR:-"${BUILDDIRECTORY}"}"
-        APTINTERNALSOLVER="${APT_INTEGRATION_TESTS_INTERNAL_SOLVER:-"${BUILDDIRECTORY}/apt-internal-solver"}"
-       APTDUMPSOLVER="${APT_INTEGRATION_TESTS_DUMP_SOLVER:-"${BUILDDIRECTORY}/apt-dump-solver"}"
-       APTINTERNALPLANNER="${APT_INTEGRATION_TESTS_INTERNAL_PLANNER:-"${BUILDDIRECTORY}/apt-internal-planner"}"
+        APTWEBSERVERBINDIR="${APT_INTEGRATION_TESTS_WEBSERVER_BIN_DIR:-"${BUILDDIRECTORY}/../test/interactive-helper"}"
+        APTFTPARCHIVEBINDIR="${APT_INTEGRATION_TESTS_FTPARCHIVE_BIN_DIR:-"${BUILDDIRECTORY}/../ftparchive"}"
+        APTINTERNALSOLVER="${APT_INTEGRATION_TESTS_INTERNAL_SOLVER:-"${BUILDDIRECTORY}/solvers/apt"}"
+       APTDUMPSOLVER="${APT_INTEGRATION_TESTS_DUMP_SOLVER:-"${BUILDDIRECTORY}/solvers/dump"}"
+       APTINTERNALPLANNER="${APT_INTEGRATION_TESTS_INTERNAL_PLANNER:-"${BUILDDIRECTORY}/planners/apt"}"
        test -x "${BUILDDIRECTORY}/apt-get" || msgdie "You need to build tree first"
         # -----
 
@@ -298,24 +335,21 @@ setupenvironment() {
        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 usr/bin var/cache var/lib var/log tmp
+       mkdir -p usr/bin var/cache var/lib var/log var/crash tmp
        mkdir -p var/lib/dpkg/info var/lib/dpkg/updates var/lib/dpkg/triggers
+       mkdir -p usr/lib/apt/solvers usr/lib/apt/planners
        touch var/lib/dpkg/available
-       mkdir -p usr/lib/apt
        ln -s "${METHODSDIR}" usr/lib/apt/methods
-       if [ "$BUILDDIRECTORY" = "$LIBRARYPATH" ]; then
-               mkdir -p usr/lib/apt/solvers usr/lib/apt/planners
-               ln -s "${BUILDDIRECTORY}/apt-dump-solver" usr/lib/apt/solvers/dump
-               ln -s "${BUILDDIRECTORY}/apt-dump-solver" usr/lib/apt/planners/dump
-               ln -s "${BUILDDIRECTORY}/apt-internal-solver" usr/lib/apt/solvers/apt
-               ln -s "${BUILDDIRECTORY}/apt-internal-planner" usr/lib/apt/planners/apt
-               echo "Dir::Bin::Solvers \"${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/solvers\";" >> ../aptconfig.conf
-               echo "Dir::Bin::Planners \"${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/planners\";" >> ../aptconfig.conf
-       fi
+       ln -s "${APTDUMPSOLVER}" usr/lib/apt/solvers/dump
+       ln -s "${APTDUMPSOLVER}" usr/lib/apt/planners/dump
+       ln -s "${APTINTERNALSOLVER}" usr/lib/apt/solvers/apt
+       ln -s "${APTINTERNALPLANNER}" usr/lib/apt/planners/apt
+       echo "Dir::Bin::Solvers \"${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/solvers\";" >> ../aptconfig.conf
+       echo "Dir::Bin::Planners \"${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/planners\";" >> ../aptconfig.conf
         # use the autoremove from the BUILDDIRECTORY if its there, otherwise
         # system
-        if [ -e "${BUILDDIRECTORY}/../../debian/apt.conf.autoremove" ]; then
-           ln -s "${BUILDDIRECTORY}/../../debian/apt.conf.autoremove" etc/apt/apt.conf.d/01autoremove
+        if [ -z "${APT_INTEGRATION_TESTS_SOURCE_DIR}" ]; then
+           ln -s "${SOURCEDIRECTORY}/debian/apt.conf.autoremove" etc/apt/apt.conf.d/01autoremove
         else
            ln -s /etc/apt/apt.conf.d/01autoremove etc/apt/apt.conf.d/01autoremove
         fi
@@ -334,7 +368,11 @@ setupenvironment() {
        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
+       echo "Dir::Etc \"etc\";" >> aptconfig.conf
+       echo "Dir::State \"var/lib/apt\";" >> aptconfig.conf
+       echo "Dir::Cache \"var/cache/apt\";" >> aptconfig.conf
+       echo "Dir::Etc \"etc/apt\";" >> aptconfig.conf
+       echo "Dir::Log \"var/log/apt\";" >> aptconfig.conf
        echo "APT::Get::Show-User-Simulation-Note \"false\";" >> aptconfig.conf
        echo "Dir::Bin::Methods \"${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/methods\";" >> aptconfig.conf
        # either store apt-key were we can access it, even if we run it as a different user
@@ -420,7 +458,7 @@ EOF
        # cleanup the environment a bit
        # prefer our apt binaries over the system apt binaries
        export PATH="${BUILDDIRECTORY}:${PATH}:/usr/local/sbin:/usr/sbin:/sbin"
-       export LC_ALL=C.UTF-8
+       export LC_ALL=C
        unset LANGUAGE APT_CONFIG
        unset GREP_OPTIONS DEB_BUILD_PROFILES
        unset http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy
@@ -433,6 +471,10 @@ EOF
        # most tests just need one signed Release file, not both
        export APT_DONT_SIGN='Release.gpg'
 
+       if [ -r "${TESTDIRECTORY}/extra-environment" ]; then
+               . "${TESTDIRECTORY}/extra-environment"
+       fi
+
        msgdone "info"
 }
 
@@ -481,17 +523,21 @@ configdpkg() {
        rm -f rootdir/etc/apt/apt.conf.d/00foreigndpkg
        if command dpkg --assert-multi-arch >/dev/null 2>&1 ; then
                local ARCHS="$(getarchitectures)"
-               if echo "$ARCHS" | grep -E -q '[^ ]+ [^ ]+'; then
-                       DPKGARCH="$(dpkg --print-architecture)"
-                       for ARCH in ${ARCHS}; do
-                               if [ "${ARCH}" != "${DPKGARCH}" ]; then
-                                       if ! dpkg --add-architecture ${ARCH} >/dev/null 2>&1; then
-                                               # old-style used e.g. in Ubuntu-P – and as it seems travis
-                                               echo "DPKG::options:: \"--foreign-architecture\";" >> rootdir/etc/apt/apt.conf.d/00foreigndpkg
-                                               echo "DPKG::options:: \"${ARCH}\";"  >> rootdir/etc/apt/apt.conf.d/00foreigndpkg
-                                       fi
+               local DPKGARCH="$(dpkg --print-architecture)"
+               # this ensures that even if multi-arch isn't active in the view
+               # of apt, given that dpkg can't be told which arch is native
+               # the arch apt treats as native might be foreign for dpkg
+               for ARCH in ${ARCHS}; do
+                       if [ "${ARCH}" != "${DPKGARCH}" ]; then
+                               if ! dpkg --add-architecture ${ARCH} >/dev/null 2>&1; then
+                                       # old-style used e.g. in Ubuntu-P – and as it seems travis
+                                       echo "DPKG::options:: \"--foreign-architecture\";" >> rootdir/etc/apt/apt.conf.d/00foreigndpkg
+                                       echo "DPKG::options:: \"${ARCH}\";"  >> rootdir/etc/apt/apt.conf.d/00foreigndpkg
                                fi
-                       done
+                       fi
+               done
+               # if multi-arch make sure dpkg can detect itself as capable of it
+               if echo "$ARCHS" | grep -E -q '[^ ]+ [^ ]+'; then
                        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
@@ -1016,13 +1062,13 @@ NotAutomatic: yes' "$dir/Release"
        fi
        if [ -n "$DATE" -a "$DATE" != "now" ]; then
                for release in $(find ./aptarchive -name 'Release'); do
-                       sed -i "s/^Date: .*$/Date: $(date -u -d "$DATE" '+%a, %d %b %Y %H:%M:%S %Z')/" "$release"
+                       sed -i "s/^Date: .*$/Date: $(date -u -d "$DATE" -R)/" "$release"
                        touch -d "$DATE" "$release"
                done
        fi
        if [ -n "$VALIDUNTIL" ]; then
                sed -i "/^Date: / a\
-Valid-Until: $(date -u -d "$VALIDUNTIL" '+%a, %d %b %Y %H:%M:%S %Z')" $(find ./aptarchive -name 'Release')
+Valid-Until: $(date -u -d "$VALIDUNTIL" -R)" $(find ./aptarchive -name 'Release')
        fi
        msgdone "info"
 }
@@ -1154,7 +1200,7 @@ signreleasefiles() {
 }
 
 redatereleasefiles() {
-       local DATE="$(date -u -d "$1" '+%a, %d %b %Y %H:%M:%S %Z')"
+       local DATE="$(date -u -d "$1" -R)"
        for release in $(find aptarchive/ -name 'Release'); do
                sed -i "s/^Date: .*$/Date: ${DATE}/" "$release"
                touch -d "$DATE" "$release"
@@ -1831,49 +1877,24 @@ testwebserverlaststatuscode() {
        msggroup
 }
 
-createlistofkeys() {
-       local OUTPUT="$1"
-       shift
+mapkeynametokeyid() {
        while [ -n "$1" ]; do
-               # gpg 2.1.something starts printing [SC] at some point
-               if grep -q ' rsa2048/' "$OUTPUT" && grep -qF '[SC]' "$OUTPUT"; then
-                       case "$1" in
-                               *Joe*|*Sixpack*) echo 'pub   rsa2048/DBAC8DAE 2010-08-18 [SC]';;
-                               *Rex*|*Expired*) echo 'pub   rsa2048/27CE74F9 2013-07-12 [SC] [expired: 2013-07-13]';;
-                               *Marvin*|*Paranoid*) echo 'pub   rsa2048/528144E2 2011-01-16 [SC]';;
-                               oldarchive) echo 'pub   rsa1024/F68C85A3 2013-12-19 [SC]';;
-                               newarchive) echo 'pub   rsa2048/DBAC8DAE 2010-08-18 [SC]';;
-                               *) echo 'UNKNOWN KEY';;
-                       esac
-               # gpg 2.1 has a slightly different output format
-               elif grep -q ' rsa2048/' "$OUTPUT"; then
-                       case "$1" in
-                               *Joe*|*Sixpack*) echo 'pub   rsa2048/DBAC8DAE 2010-08-18';;
-                               *Rex*|*Expired*) echo 'pub   rsa2048/27CE74F9 2013-07-12 [expired: 2013-07-13]';;
-                               *Marvin*|*Paranoid*) echo 'pub   rsa2048/528144E2 2011-01-16';;
-                               oldarchive) echo 'pub   rsa1024/F68C85A3 2013-12-19';;
-                               newarchive) echo 'pub   rsa2048/DBAC8DAE 2010-08-18';;
-                               *) echo 'UNKNOWN KEY';;
-                       esac
-               else
-                       case "$1" in
-                               *Joe*|*Sixpack*) echo 'pub   2048R/DBAC8DAE 2010-08-18';;
-                               *Rex*|*Expired*) echo 'pub   2048R/27CE74F9 2013-07-12 [expired: 2013-07-13]';;
-                               *Marvin*|*Paranoid*) echo 'pub   2048R/528144E2 2011-01-16';;
-                               oldarchive) echo 'pub   1024R/F68C85A3 2013-12-19';;
-                               newarchive) echo 'pub   2048R/DBAC8DAE 2010-08-18';;
-                               *) echo 'UNKNOWN KEY';;
-                       esac
-               fi
+               case "$1" in
+                       *Joe*|*Sixpack*|newarchive) echo '5A90D141DBAC8DAE';;
+                       *Rex*|*Expired*) echo '4BC0A39C27CE74F9';;
+                       *Marvin*|*Paranoid*) echo 'E8525D47528144E2';;
+                       oldarchive) echo 'FDD2DB85F68C85A3';;
+                       *) echo 'UNKNOWN KEY';;
+               esac
                shift
        done
 }
 testaptkeys() {
        local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/aptkeylist.output"
-       if ! aptkey list | grep '^pub' > "$OUTPUT"; then
+       if ! aptkey list --with-colon | grep '^pub' | cut -d':' -f 5 > "$OUTPUT"; then
                echo -n > "$OUTPUT"
        fi
-       testfileequal "$OUTPUT" "$(createlistofkeys "$OUTPUT" "$@")"
+       testfileequal "$OUTPUT" "$(mapkeynametokeyid "$@")"
 }
 
 pause() {
@@ -1882,6 +1903,11 @@ pause() {
        read IGNORE
 }
 
+logcurrentarchivedirectory() {
+       find "${TMPWORKINGDIRECTORY}/aptarchive/dists" -type f | while read line; do
+               stat --format '%U:%G:%a:%n' "$line"
+       done | sort > "${TMPWORKINGDIRECTORY}/rootdir/var/log/aptgetupdate.before.lst"
+}
 listcurrentlistsdirectory() {
        {
                find rootdir/var/lib/apt/lists -maxdepth 1 -type d | while read line; do
@@ -1922,12 +1948,20 @@ mkdir() {
 ### general things about commands executed without writing the test every time.
 
 aptautotest() {
+       if [ $# -lt 3 ]; then return; fi
        local TESTCALL="$1"
        local CMD="$2"
        local FIRSTOPT="$3"
+       shift 2
+       for i in "$@"; do
+               if ! expr match "$i" '^-' >/dev/null 2>&1; then
+                       FIRSTOPT="$i"
+                       break
+               fi
+       done
+       shift
        local AUTOTEST="aptautotest_$(echo "${CMD##*/}_${FIRSTOPT}" | tr -d -c 'A-za-z0-9')"
        if command -v $AUTOTEST >/dev/null; then
-               shift 3
                # save and restore the *.output files from other tests
                # as we might otherwise override them in these automatic tests
                rm -rf "${TMPWORKINGDIRECTORY}/rootdir/tmp-before"
@@ -1960,6 +1994,10 @@ aptautotest_aptget_update() {
                # failure cases can retain partial files and such
                testempty find "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial" -mindepth 1 ! \( -name 'lock' -o -name '*.FAILED' \)
        fi
+       if [ -s "${TMPWORKINGDIRECTORY}/rootdir/var/log/aptgetupdate.before.lst" ]; then
+               testfileequal "${TMPWORKINGDIRECTORY}/rootdir/var/log/aptgetupdate.before.lst" \
+                       "$(find "${TMPWORKINGDIRECTORY}/aptarchive/dists" -type f | while read line; do stat --format '%U:%G:%a:%n' "$line"; done | sort)"
+       fi
 }
 aptautotest_apt_update() { aptautotest_aptget_update "$@"; }
 aptautotest_aptcdrom_add() { aptautotest_aptget_update "$@"; }
@@ -1980,3 +2018,11 @@ aptautotest_aptget_purge() { testaptautotestnodpkgwarning "$@"; }
 aptautotest_apt_install() { testaptautotestnodpkgwarning "$@"; }
 aptautotest_apt_remove() { testaptautotestnodpkgwarning "$@"; }
 aptautotest_apt_purge() { testaptautotestnodpkgwarning "$@"; }
+
+testaptmarknodefaultsections() {
+       testfailure grep '^Auto-Installed: 0$' "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/extended_states"
+}
+aptautotest_aptmark_auto() { testaptmarknodefaultsections "$@"; }
+aptautotest_aptmark_manual() { testaptmarknodefaultsections "$@"; }
+aptautotest_aptget_markauto() { testaptmarknodefaultsections "$@"; }
+aptautotest_aptget_markmanual() { testaptmarknodefaultsections "$@"; }