X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/63c7141275c8c5c0f6e60f5242785e50cabaf2a0..d27daedb6a0bf672508072100f20233d08ccf0e0:/test/integration/framework diff --git a/test/integration/framework b/test/integration/framework index 83f93217f..8ea1e1c0d 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -9,6 +9,14 @@ while [ -n "$1" ]; do export MSGLEVEL=4 elif [ "$1" = '--color=no' ]; then export MSGCOLOR='NO' + elif [ "$1" = '--color=yes' ]; then + export MSGCOLOR='YES' + elif [ "$1" = '--color' ]; then + export MSGCOLOR="$(echo "$2" | tr 'a-z' 'A-Z')" + shift + elif [ "$1" = '--level' ]; then + export MSGLEVEL=$2 + shift else echo >&2 "WARNING: Unknown parameter »$1« will be ignored" fi @@ -17,7 +25,7 @@ done export MSGLEVEL="${MSGLEVEL:-3}" # we all like colorful messages -if [ "$MSGCOLOR" != 'NO' ] && [ "$MSGCOLOR" != 'ALWAYS' ]; then +if [ "${MSGCOLOR:-YES}" = 'YES' ]; then if [ ! -t 1 ]; then # but check that we output to a terminal export MSGCOLOR='NO' fi @@ -309,14 +317,14 @@ setupenvironment() { echo "Dir::state::status \"${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status\";" >> aptconfig.conf echo "APT::Get::Show-User-Simulation-Note \"false\";" >> aptconfig.conf echo "Dir::Bin::Methods \"${TMPWORKINGDIRECTORY}/rootdir/usr/lib/apt/methods\";" >> aptconfig.conf - # store apt-key were we can access it, even if we run it as a different user - # destroys coverage reporting though, so just do it for root for now + # either store apt-key were we can access it, even if we run it as a different user + #cp "${BUILDDIRECTORY}/apt-key" "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/" + #chmod o+rx "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apt-key" + #echo "Dir::Bin::apt-key \"${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apt-key\";" >> aptconfig.conf + # destroys coverage reporting though, so we disable changing user for the calling gpgv + echo "Dir::Bin::apt-key \"${BUILDDIRECTORY}/apt-key\";" >> aptconfig.conf if [ "$(id -u)" = '0' ]; then - cp "${BUILDDIRECTORY}/apt-key" "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/" - chmod o+rx "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apt-key" - echo "Dir::Bin::apt-key \"${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apt-key\";" >> aptconfig.conf - else - echo "Dir::Bin::apt-key \"${BUILDDIRECTORY}/apt-key\";" >> aptconfig.conf + echo 'Binary::gpgv::Debug::NoDropPrivs "true";' >>aptconfig.conf fi cat > "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" </dev/null 2>&1; then echo "DPKG::options:: \"--force-architecture\";" # Added to test multiarch before dpkg is ready for it… fi + echo 'quiet "0";' echo 'quiet::NoUpdate "true";' echo 'quiet::NoStatistic "true";' # too distracting for users, but helpful to detect changes @@ -361,6 +370,8 @@ EOF # in testcases, it can appear as if localhost has a rotation setup, # hide this as we can't really deal with it properly echo 'Acquire::Failure::ShowIP "false";' + # fakeroot can't fake everything, so disabled in production but good for tests + echo 'APT::Sandbox::Verify "true";' } >> aptconfig.conf cp "${TESTDIRECTORY}/apt.pem" "${TMPWORKINGDIRECTORY}/rootdir/etc/webserver.pem" @@ -369,23 +380,20 @@ EOF fi echo "Acquire::https::CaInfo \"${TMPWORKINGDIRECTORY}/rootdir/etc/webserver.pem\";" > rootdir/etc/apt/apt.conf.d/99https echo "Apt::Cmd::Disable-Script-Warning \"1\";" > rootdir/etc/apt/apt.conf.d/apt-binary + echo 'Acquire::Connect::AddrConfig "false";' > rootdir/etc/apt/apt.conf.d/connect-addrconfig configcompression '.' 'gz' #'bz2' 'lzma' 'xz' confighashes 'SHA1' # these are tests, not security best-practices # create some files in /tmp and look at user/group to get what this means - TEST_DEFAULT_USER="$USER" + TEST_DEFAULT_USER="$(id -un)" if [ "$(uname)" = 'GNU/kFreeBSD' ]; then TEST_DEFAULT_GROUP='root' else - TEST_DEFAULT_GROUP="$USER" + TEST_DEFAULT_GROUP="$(id -gn)" fi - # Acquire::AllowInsecureRepositories=false is not yet the default - # but we want it to be the default soon - configallowinsecurerepositories "false"; - # cleanup the environment a bit - # prefer our apt binaries over the system apt binaries + # 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 unset LANGUAGE APT_CONFIG @@ -469,6 +477,7 @@ configdpkgnoopchroot() { #include #include #include +#include static char * chrootdir = NULL; @@ -485,25 +494,17 @@ int execvp(const char *file, char *const argv[]) { if (chrootdir == NULL || strncmp(file, "/var/lib/dpkg/", strlen("/var/lib/dpkg/")) != 0) return func_execvp(file, argv); printf("REWRITE execvp call %s into %s\n", file, chrootdir); - char newfile[strlen(chrootdir) + strlen(file)]; - strcpy(newfile, chrootdir); - strcat(newfile, file); + char newfile[PATH_MAX]; + snprintf(newfile, sizeof(newfile), "%s/%s", chrootdir, file); char const * const baseadmindir = "/var/lib/dpkg"; - char admindir[strlen(chrootdir) + strlen(baseadmindir)]; - strcpy(admindir, chrootdir); - strcat(admindir, baseadmindir); + char admindir[PATH_MAX]; + snprintf(admindir, sizeof(admindir), "%s/%s", chrootdir, baseadmindir); setenv("DPKG_ADMINDIR", admindir, 1); return func_execvp(newfile, argv); } EOF testsuccess --nomsg gcc -fPIC -shared -o noopchroot.so noopchroot.c -ldl } - -configallowinsecurerepositories() { - echo "Acquire::AllowInsecureRepositories \"$1\";" > rootdir/etc/apt/apt.conf.d/allow-insecure-repositories.conf - -} - configcompression() { while [ -n "$1" ]; do case "$1" in @@ -572,7 +573,7 @@ setupsimplenativepackage() { local DESCRIPTION="${6:-"an autogenerated dummy ${NAME}=${VERSION}/${RELEASE} If you find such a package installed on your system, something went horribly wrong! They are autogenerated - und used only by testcases and surf no other propose…"}" + und used only by testcases and serve no other purpose…"}" local SECTION="${7:-others}" local DISTSECTION @@ -628,7 +629,7 @@ buildsimplenativepackage() { local DESCRIPTION="${6:-"an autogenerated dummy ${NAME}=${VERSION}/${RELEASE} If you find such a package installed on your system, something went horribly wrong! They are autogenerated - und used only by testcases and surf no other propose…"}" + und used only by testcases and serve no other purpose…"}" local SECTION="${7:-others}" local PRIORITY="${8:-optional}" @@ -776,7 +777,7 @@ EOF for DIST in $(find ./pool/ -maxdepth 1 -name '*.pkglist' -type f | cut -d'/' -f 3 | cut -d'.' -f 1 | sort | uniq); do cat < "$dir/Release" if [ "$SUITE" = "experimental" -o "$SUITE" = "experimental2" ]; then sed -i '/^Date: / a\ @@ -1001,17 +998,18 @@ NotAutomatic: yes' "$dir/Release" fi done else + msgninfo "\tGenerate Release files for flat… " aptftparchiverelease ./aptarchive > aptarchive/Release fi - if [ -n "$1" -a "$1" != "now" ]; then + if [ -n "$DATE" -a "$DATE" != "now" ]; then for release in $(find ./aptarchive -name 'Release'); do - sed -i "s/^Date: .*$/Date: $(date -d "$1" '+%a, %d %b %Y %H:%M:%S %Z')/" "$release" - touch -d "$1" "$release" + sed -i "s/^Date: .*$/Date: $(date -d "$DATE" '+%a, %d %b %Y %H:%M:%S %Z')/" "$release" + touch -d "$DATE" "$release" done fi - if [ -n "$2" ]; then + if [ -n "$VALIDUNTIL" ]; then sed -i "/^Date: / a\ -Valid-Until: $(date -d "$2" '+%a, %d %b %Y %H:%M:%S %Z')" $(find ./aptarchive -name 'Release') +Valid-Until: $(date -d "$VALIDUNTIL" '+%a, %d %b %Y %H:%M:%S %Z')" $(find ./aptarchive -name 'Release') fi msgdone "info" } @@ -1119,7 +1117,7 @@ redatereleasefiles() { } webserverconfig() { - local WEBSERVER="${3:-http://localhost:8080}" + local WEBSERVER="${3:-http://localhost:${APTHTTPPORT}}" local NOCHECK=false if [ "$1" = '--no-check' ]; then NOCHECK=true @@ -1128,13 +1126,14 @@ webserverconfig() { local DOWNLOG='rootdir/tmp/download-testfile.log' local STATUS='downloaded/webserverconfig.status' rm -f "$STATUS" "$DOWNLOG" + # very very basic URI encoding local URI if [ -n "$2" ]; then msgtest "Set webserver config option '${1}' to" "$2" - URI="${WEBSERVER}/_config/set/${1}/${2}" + URI="${WEBSERVER}/_config/set/$(echo "${1}" | sed -e 's/\//%2f/g')/$(echo "${2}" | sed -e 's/\//%2f/g')" else msgtest 'Clear webserver config option' "${1}" - URI="${WEBSERVER}/_config/clear/${1}" + URI="${WEBSERVER}/_config/clear/$(echo "${1}" | sed -e 's/\//%2f/g')" fi if downloadfile "$URI" "$STATUS" > "$DOWNLOG"; then msgpass @@ -1148,8 +1147,11 @@ webserverconfig() { rewritesourceslist() { local APTARCHIVE="file://$(readlink -f "${TMPWORKINGDIRECTORY}/aptarchive" | sed 's# #%20#g')" + local APTARCHIVE2="copy://$(readlink -f "${TMPWORKINGDIRECTORY}/aptarchive" | sed 's# #%20#g')" for LIST in $(find rootdir/etc/apt/sources.list.d/ -name 'apt-test-*.list'); do - sed -i $LIST -e "s#$APTARCHIVE#${1}#" -e "s#http://localhost:8080/#${1}#" -e "s#https://localhost:4433/#${1}#" + sed -i $LIST -e "s#$APTARCHIVE#${1}#" -e "s#$APTARCHIVE2#${1}#" \ + -e "s#http://localhost:${APTHTTPPORT}/#${1}#" \ + -e "s#https://localhost:${APTHTTPSPORT}/#${1}#" done } @@ -1168,32 +1170,41 @@ waitforpidfile() { } changetowebserver() { + local REWRITE='no' if [ "$1" != '--no-rewrite' ]; then - rewritesourceslist 'http://localhost:8080/' + REWRITE='yes' else shift fi if test -x "${APTWEBSERVERBINDIR}/aptwebserver"; then cd aptarchive local LOG="webserver.log" - if ! aptwebserver -o aptwebserver::fork=1 "$@" >$LOG 2>&1 ; then + if ! aptwebserver --port 0 -o aptwebserver::fork=1 -o aptwebserver::portfile='aptwebserver.port' "$@" >$LOG 2>&1 ; then cat $LOG false fi - waitforpidfile aptwebserver.pid + waitforpidfile aptwebserver.pid local PID="$(cat aptwebserver.pid)" if [ -z "$PID" ]; then msgdie 'Could not fork aptwebserver successfully' fi addtrap "kill $PID;" + waitforpidfile aptwebserver.port + APTHTTPPORT="$(cat aptwebserver.port)" + if [ -z "$APTHTTPPORT" ]; then + msgdie 'Could not get port for aptwebserver successfully' + fi cd - > /dev/null else - msgdie 'You have to build aptwerbserver or install a webserver' + msgdie 'You have to build apt from source to have test/interactive-helper/aptwebserver available for tests requiring a webserver' + fi + if [ "$REWRTE" != 'yes' ]; then + rewritesourceslist "http://localhost:${APTHTTPPORT}/" fi } changetohttpswebserver() { - if ! which stunnel4 >/dev/null; then + if ! command -v stunnel4 >/dev/null 2>&1; then msgdie 'You need to install stunnel4 for https testcases' fi if [ ! -e "${TMPWORKINGDIRECTORY}/aptarchive/aptwebserver.pid" ]; then @@ -1204,8 +1215,8 @@ cert = ${TMPWORKINGDIRECTORY}/rootdir/etc/webserver.pem output = /dev/null [https] -accept = 4433 -connect = 8080 +accept = 0 +connect = $APTHTTPPORT " > "${TMPWORKINGDIRECTORY}/stunnel.conf" stunnel4 "${TMPWORKINGDIRECTORY}/stunnel.conf" waitforpidfile "${TMPWORKINGDIRECTORY}/aptarchive/stunnel.pid" @@ -1214,7 +1225,9 @@ connect = 8080 msgdie 'Could not fork stunnel4 successfully' fi addtrap 'prefix' "kill ${PID};" - rewritesourceslist 'https://localhost:4433/' + APTHTTPSPORT="$(lsof -i | awk "/^stunnel4 / && \$2 == \"${PID}\" {print \$9; exit; }" | cut -d':' -f 2)" + webserverconfig 'aptwebserver::port::https' "$APTHTTPSPORT" "https://localhost:${APTHTTPSPORT}" + rewritesourceslist "https://localhost:${APTHTTPSPORT}/" } changetocdrom() { @@ -1389,7 +1402,7 @@ N: No packages found" local ARCH="$(getarchitecture 'native')" echo "$VIRTUAL" | sed -e "s/:$ARCH//" -e 's/:all//' >"$COMPAREFILE" local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testshowvirtual.output" - testoutputequal "$COMPAREFILE" aptcache show -q=0 "$PACKAGE" + testoutputequal "$COMPAREFILE" aptcache show "$PACKAGE" msggroup } @@ -1406,6 +1419,19 @@ testnopackage() { fi msggroup } +testnosrcpackage() { + msggroup 'testnosrcpackage' + msgtest "Test for non-existent source packages" "apt-cache showsrc $*" + local SHOWPKG="$(aptcache showsrc "$@" 2>&1 | grep '^Package: ')" + if [ -n "$SHOWPKG" ]; then + local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testnosrcpackage.output" + echo "$SHOWPKG" >"$OUTPUT" + msgfailoutput '' "$OUTPUT" + else + msgpass + fi + msggroup +} testdpkgstatus() { msggroup 'testdpkgstatus' @@ -1483,7 +1509,10 @@ msgfailoutput() { if expr match "$1" "$FILEFLAGS" >/dev/null; then echo "#### stat(2) of file: $2 ####" stat "$2" || true - if test -e "$2"; then + if test -d "$2"; then + echo "#### The directory contains: $2 ####" + ls >&2 "$2" || true + elif test -e "$2"; then echo "#### Complete file: $2 ####" cat >&2 "$2" || true fi @@ -1500,19 +1529,22 @@ msgfailoutput() { msgfail "$MSG" } -testsuccess() { - msggroup 'testsuccess' +testsuccesswithglobalerror() { + local TYPE="$1" + local ERRORS="$2" + shift 2 + msggroup "$TYPE" if [ "$1" = '--nomsg' ]; then shift else msgtest 'Test for successful execution of' "$*" fi - local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testsuccess.output" + local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/${TYPE}.output" if "$@" >"${OUTPUT}" 2>&1; then if expr match "$1" '^apt.*' >/dev/null; then if grep -q -E ' runtime error: ' "$OUTPUT"; then msgfailoutput 'compiler detected undefined behavior' "$OUTPUT" "$@" - elif grep -E '^[WE]: ' "$OUTPUT" > "${TMPWORKINGDIRECTORY}/rootdir/tmp/checkforwarnings.output" 2>&1; then + elif grep -E "^[${ERRORS}]: " "$OUTPUT" > "${TMPWORKINGDIRECTORY}/rootdir/tmp/checkforwarnings.output" 2>&1; then if [ "$IGNORE_PTY_NOT_MOUNTED" = '1' ]; then if echo 'E: Can not write log (Is /dev/pts mounted?) - posix_openpt (2: No such file or directory)' \ | cmp - "${TMPWORKINGDIRECTORY}/rootdir/tmp/checkforwarnings.output" >/dev/null 2>&1; then @@ -1523,6 +1555,12 @@ testsuccess() { else msgfailoutput 'successful run, but output contains warnings/errors' "$OUTPUT" "$@" fi + elif [ "$TYPE" = 'testsuccesswithnotice' ]; then + if grep -q -E "^N: " "$OUTPUT"; then + msgpass + else + msgfailoutput 'successful run, but output had no notices' "$OUTPUT" "$@" + fi else msgpass fi @@ -1533,9 +1571,15 @@ testsuccess() { local EXITCODE=$? msgfailoutput "exitcode $EXITCODE" "$OUTPUT" "$@" fi - aptautotest 'testsuccess' "$@" + aptautotest "$TYPE" "$@" msggroup } +testsuccesswithnotice() { + testsuccesswithglobalerror 'testsuccesswithnotice' 'WE' "$@" +} +testsuccess() { + testsuccesswithglobalerror 'testsuccess' 'NWE' "$@" +} testwarning() { msggroup 'testwarning' if [ "$1" = '--nomsg' ]; then @@ -1607,22 +1651,41 @@ testfailure() { testreturnstateequal() { local STATE="$1" - msggroup "${STATE}equal" - if [ "$2" != '--nomsg' ]; then - local CMP="$2" - shift 2 - "$STATE" "$@" - testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/${STATE}.output" "$CMP" - else - local CMP="$3" + if [ "$STATE" = 'testsuccesswithglobalerror' ]; then + local STATE="$2" + local TYPE="$3" shift 3 - "$STATE" --nomsg "$@" - testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/${STATE}.output" "$CMP" + msggroup "${STATE}equal" + if [ "$1" != '--nomsg' ]; then + local CMP="$1" + shift + testsuccesswithglobalerror "$STATE" "$TYPE" "$@" + testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/${STATE}.output" "$CMP" + else + local CMP="$2" + shift 2 + testsuccesswithglobalerror "$STATE" "$TYPE" "$@" + testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/${STATE}.output" "$CMP" + fi + else + msggroup "${STATE}equal" + if [ "$2" != '--nomsg' ]; then + local CMP="$2" + shift 2 + "$STATE" "$@" + testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/${STATE}.output" "$CMP" + else + local CMP="$3" + shift 3 + "$STATE" --nomsg "$@" + testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/${STATE}.output" "$CMP" + fi fi msggroup } testsuccessequal() { - testreturnstateequal 'testsuccess' "$@" + # we compare output, so we know perfectly well about N: + testreturnstateequal 'testsuccesswithglobalerror' 'testsuccess' 'WE' "$@" } testwarningequal() { testreturnstateequal 'testwarning' "$@" @@ -1638,7 +1701,18 @@ testfailuremsg() { testfailure "$@" msgtest 'Check that the output of the previous failed command has expected' 'failures and warnings' local COMPAREFILE="${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailuremsg.comparefile" - grep '^\(W\|E\):' "${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailure.output" > "$COMPAREFILE" 2>&1 || true + grep '^\(W\|E\|N\):' "${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailure.output" > "$COMPAREFILE" 2>&1 || true + testoutputequal "$COMPAREFILE" echo "$CMP" + msggroup +} +testwarningmsg() { + msggroup 'testwarningmsg' + local CMP="$1" + shift + testwarning "$@" + msgtest 'Check that the output of the previous warned command has expected' 'warnings' + local COMPAREFILE="${TMPWORKINGDIRECTORY}/rootdir/tmp/testwarningmsg.comparefile" + grep '^\(W\|E\|N\):' "${TMPWORKINGDIRECTORY}/rootdir/tmp/testwarning.output" > "$COMPAREFILE" 2>&1 || true testoutputequal "$COMPAREFILE" echo "$CMP" msggroup } @@ -1671,7 +1745,7 @@ testwebserverlaststatuscode() { local STATUS='downloaded/webserverstatus-statusfile.log' rm -f "$DOWNLOG" "$STATUS" msgtest 'Test last status code from the webserver was' "$1" - if downloadfile "http://localhost:8080/_config/find/aptwebserver::last-status-code" "$STATUS" > "$DOWNLOG" && [ "$(cat "$STATUS")" = "$1" ]; then + if downloadfile "http://localhost:${APTHTTPPORT}/_config/find/aptwebserver::last-status-code" "$STATUS" > "$DOWNLOG" && [ "$(cat "$STATUS")" = "$1" ]; then msgpass else local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testwebserverlaststatuscode.output" @@ -1709,8 +1783,8 @@ listcurrentlistsdirectory() { ### convenience hacks ### mkdir() { # creating some directories by hand is a tedious task, so make it look simple - if [ "$*" = '-p rootdir/var/lib/apt/lists' ] || [ "$*" = "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" ] || - [ "$*" = '-p rootdir/var/lib/apt/lists/partial' ] || [ "$*" = "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial" ]; then + local PARAMS="$*" + if [ "$PARAMS" != "${PARAMS#*rootdir/var/lib/apt/lists}" ]; then # only the last directory created by mkdir is effected by the -m ! command mkdir -m 755 -p "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt" command mkdir -m 755 -p "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists"