From ad7e0941b376d792911f240377094a2e78ca8756 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 8 Nov 2014 18:14:46 +0100 Subject: streamline display of --help in all tools By convention, if I run a tool with --help or --version I expect it to exit successfully with the usage, while if I do call it wrong (like without any parameters) I expect the usage message shown with a non-zero exit. --- test/integration/framework | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test/integration/framework') diff --git a/test/integration/framework b/test/integration/framework index 153c5bb25..dd66f2a0c 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -128,6 +128,7 @@ aptwebserver() { runapt "${APTWEBSERVERBINDIR}/aptwebserver" "$@"; } aptitude() { runapt aptitude "$@"; } aptextracttemplates() { runapt apt-extracttemplates "$@"; } aptinternalsolver() { runapt "${APTINTERNALSOLVER}" "$@"; } +aptdumpsolver() { runapt "${APTDUMPSOLVER}" "$@"; } dpkg() { command dpkg --root=${TMPWORKINGDIRECTORY}/rootdir --force-not-root --force-bad-path --log=${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log "$@" @@ -194,6 +195,7 @@ setupenvironment() { 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"} test -x "${BUILDDIRECTORY}/apt-get" || msgdie "You need to build tree first" # ----- -- cgit v1.2.3-70-g09d2 From 061ee5f0efa9d8e8fe4796c13af68fe282a21073 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 8 Nov 2014 22:23:19 +0100 Subject: enhance apt-extracttemplates test The tool checks for debconf version before printing the info it extracts, so that it doesn't extract data which can't be interpreted before debconf is upgraded. It is only fair to check for this behaviour in the tests. Git-Dch: Ignore --- test/integration/framework | 1 + test/integration/test-apt-extracttemplates | 69 ++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 22 deletions(-) (limited to 'test/integration/framework') diff --git a/test/integration/framework b/test/integration/framework index dd66f2a0c..0da9e2aab 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1110,6 +1110,7 @@ testempty() { if "$@" >$COMPAREFILE 2>&1 && test ! -s $COMPAREFILE; then msgpass else + echo cat $COMPAREFILE msgfail fi diff --git a/test/integration/test-apt-extracttemplates b/test/integration/test-apt-extracttemplates index ae2cc8bc2..276862464 100755 --- a/test/integration/test-apt-extracttemplates +++ b/test/integration/test-apt-extracttemplates @@ -8,38 +8,63 @@ setupenvironment configarchitecture 'amd64' # apt-extracttemplates needs this -insertinstalledpackage 'debconf' 'amd64' '1.5' insertinstalledpackage 'pkg-with-template' 'amd64' '1.0' # build a simple package that contains a config and a tempalte mkdir -p DEBIAN -TEMPLATE_STR="Template: foo/bar -Type: string -Description: Some bar var -" -echo "$TEMPLATE_STR" > DEBIAN/templates - CONFIG_STR="#!/bin/sh random shell stuff " echo "$CONFIG_STR" > DEBIAN/config -buildsimplenativepackage 'pkg-with-template' 'amd64' '0.8.15' 'stable' '' 'pkg with template' '' '' './DEBIAN' +testrun() { + local TEMPLATE_STR='Template: foo/bar +Type: string +Description: Some bar var +' + echo "$TEMPLATE_STR" > DEBIAN/templates + buildsimplenativepackage "$1" 'amd64' '0.8.15' 'stable' "$2" 'pkg with template' '' '' './DEBIAN' + + cp dpkg.status rootdir/var/lib/dpkg/status + insertinstalledpackage 'debconf' 'amd64' '3' + + # ensure we get the right stuff out of the file + rm -rf extracttemplates-out rootdir/var/cache/apt + mkdir extracttemplates-out + testsuccess aptextracttemplates -t ./extracttemplates-out incoming/${1}*.deb + OUT='rootdir/tmp/testsuccess.output' + testequal "$1" cut -f1 -d' ' $OUT + if [ -n "$2" ]; then + testequal '' cut -f2 -d' ' $OUT + else + testequal '1.0' cut -f2 -d' ' $OUT + fi + TEMPLATE=$(cut -f3 -d' ' $OUT) + testfileequal "$TEMPLATE" "$TEMPLATE_STR" + CONFIG=$(cut -f4 -d' ' $OUT) + testfileequal "$CONFIG" "$CONFIG_STR" -# ensure we get the right stuff out of the file -mkdir extracttemplates-out -OUT="$(aptextracttemplates -t ./extracttemplates-out incoming/pkg-with-template*.deb)" + # ensure that the format of the output string has the right number of dots + for s in "$CONFIG" "$TEMPLATE"; do + NR_DOTS=$(basename "$s" | tr -c -d '.') + testequal '..' echo $NR_DOTS + done -PKG=$(printf "$OUT" | cut -f1 -d' ') -INSTALLED_VER=$(printf "$OUT" | cut -f2 -d' ') -TEMPLATE=$(printf "$OUT" | cut -f3 -d' ') -CONFIG=$(printf "$OUT" | cut -f4 -d' ') + if [ -n "$2" ]; then + rm -rf extracttemplates-out rootdir/var/cache/apt + mkdir extracttemplates-out + cp dpkg.status rootdir/var/lib/dpkg/status + insertinstalledpackage 'debconf' 'amd64' '1' + testempty aptextracttemplates -t ./extracttemplates-out incoming/${1}*.deb + fi +} -testequal "$CONFIG_STR" cat $CONFIG -testequal "$TEMPLATE_STR" cat $TEMPLATE +cp rootdir/var/lib/dpkg/status dpkg.status +testrun 'pkg-with-template' '' +testrun 'pkg-with-template-depends' 'Depends: debconf (>= 2)' +testrun 'pkg-with-template-predepends' 'Pre-Depends: debconf (>= 2)' -# ensure that the format of the output string has the right number of dots -for s in "$CONFIG" "$TEMPLATE"; do - NR_DOTS=$(basename "$s" | tr -c -d .) - testequal ".." echo $NR_DOTS -done +# test with no debconf installed +cp dpkg.status rootdir/var/lib/dpkg/status +testfailure aptextracttemplates -t ./extracttemplates-out incoming/pkg-with-template-depends*.deb +testfileequal 'rootdir/tmp/testfailure.output' 'E: Cannot get debconf version. Is debconf installed?' -- cgit v1.2.3-70-g09d2 From 546dbfc82ad9ff0308b365bca3731a1118b1d251 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 9 Nov 2014 21:26:20 +0100 Subject: disable the lock disabling in the tests We create our own directories here and work without root in them, so we can also test the locking with them as it is how we usually operate. Git-Dch: Ignore --- test/integration/framework | 3 +-- test/integration/test-apt-get-update-unauth-warning | 5 +++-- test/integration/test-apt-update-transactions | 1 + test/integration/test-ubuntu-bug-346386-apt-get-update-paywall | 3 ++- 4 files changed, 7 insertions(+), 5 deletions(-) (limited to 'test/integration/framework') diff --git a/test/integration/framework b/test/integration/framework index 0da9e2aab..d28085ee4 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -236,7 +236,6 @@ setupenvironment() { echo "Dir \"${TMPWORKINGDIRECTORY}/rootdir\";" > aptconfig.conf echo "Dir::state::status \"${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status\";" >> aptconfig.conf - echo "Debug::NoLocking \"true\";" >> aptconfig.conf echo "APT::Get::Show-User-Simulation-Note \"false\";" >> aptconfig.conf echo "Dir::Bin::Methods \"${METHODSDIR}\";" >> aptconfig.conf # store apt-key were we can access it, even if we run it as a different user @@ -1412,7 +1411,7 @@ aptautotest() { aptautotest_aptget_update() { if ! test -d "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists"; then return; fi # all copied files are properly chmodded - for file in $(find "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" -maxdepth 1 -type f); do + for file in $(find "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" -maxdepth 1 -type f ! -name 'lock'); do testfilestats "$file" '%U:%G:%a' '=' "${USER}:${USER}:644" done } diff --git a/test/integration/test-apt-get-update-unauth-warning b/test/integration/test-apt-get-update-unauth-warning index 0389415c1..80c51152d 100755 --- a/test/integration/test-apt-get-update-unauth-warning +++ b/test/integration/test-apt-get-update-unauth-warning @@ -27,8 +27,9 @@ W: The repository 'file: unstable Release' does not have a Release file. This is E: Use --allow-insecure-repositories to force the update" aptget update --no-allow-insecure-repositories # no package foo -testequal "Listing..." apt list foo -testequal "partial" ls rootdir/var/lib/apt/lists +testequal 'Listing...' apt list foo +testequal 'lock +partial' ls rootdir/var/lib/apt/lists # allow override testequal "Ign file: unstable InRelease diff --git a/test/integration/test-apt-update-transactions b/test/integration/test-apt-update-transactions index fe352c762..bf425a22e 100755 --- a/test/integration/test-apt-update-transactions +++ b/test/integration/test-apt-update-transactions @@ -49,6 +49,7 @@ testsetup() { msgmsg 'Test with no initial data over' "$1" rm -rf rootdir/var/lib/apt/lists mkdir -m 700 -p rootdir/var/lib/apt/lists/partial + touch rootdir/var/lib/apt/lists/lock if [ "$(id -u)" = '0' ]; then chown _apt:root rootdir/var/lib/apt/lists/partial fi diff --git a/test/integration/test-ubuntu-bug-346386-apt-get-update-paywall b/test/integration/test-ubuntu-bug-346386-apt-get-update-paywall index df2c69cf6..ea516fc12 100755 --- a/test/integration/test-ubuntu-bug-346386-apt-get-update-paywall +++ b/test/integration/test-ubuntu-bug-346386-apt-get-update-paywall @@ -40,7 +40,8 @@ msgtest 'Got expected failure message' 'apt-get update' aptget update -qq 2>&1 | grep -q 'W:.*Does not start with a cleartext signature' && msgpass || msgfail ensure_n_canary_strings_in_dir $LISTS 'ni ni ni' 0 -testequal 'partial' ls $LISTS +testequal 'lock +partial' ls $LISTS # and again with pre-existing files with "valid data" which should remain for f in Release Release.gpg main_binary-amd64_Packages main_source_Sources; do -- cgit v1.2.3-70-g09d2 From 081c9d442a6d39fb9bc419fe3ce697cc791cb844 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 9 Nov 2014 21:38:53 +0100 Subject: various small additional tests and testcases Usually they don't provide a lot in terms of what they test, but they help in covering many lines from strictly anecdotal commands (stats, moo) and error messages, so that stuff which really needs to be tested, but isn't is better visible in coverage reports. Git-Dch: Ignore --- cmdline/apt-cache.cc | 4 +- test/integration/framework | 2 +- test/integration/test-00-commands-have-help | 11 ++ test/integration/test-apt-cache | 124 +++++++++++++++++++++ test/integration/test-apt-cli-search | 3 + test/integration/test-apt-cli-show | 11 ++ test/integration/test-apt-cli-update | 7 ++ test/integration/test-apt-config | 36 ++++++ test/integration/test-apt-helper | 12 +- test/integration/test-apt-mark | 34 ++++-- test/integration/test-apt-update-stale | 6 +- .../test-external-dependency-solver-protocol | 32 +++++- 12 files changed, 263 insertions(+), 19 deletions(-) create mode 100755 test/integration/test-apt-cache create mode 100755 test/integration/test-apt-config (limited to 'test/integration/framework') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 342ad1858..a5024c581 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -116,7 +116,7 @@ static bool ShowUnMet(pkgCache::VerIterator const &V, bool const Important) continue; // Skip conflicts and replaces - if (End.IsNegative() == true) + if (End.IsNegative() == true || End->Type == pkgCache::Dep::Replaces) continue; // Verify the or group @@ -133,7 +133,7 @@ static bool ShowUnMet(pkgCache::VerIterator const &V, bool const Important) break; } delete [] VList; - + if (Start == End) break; ++Start; diff --git a/test/integration/framework b/test/integration/framework index d28085ee4..c9f62c141 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -300,7 +300,7 @@ getarchitecture() { } getarchitectures() { - echo "$(aptconfig dump | grep APT::Architecture | cut -d'"' -f 2 | sed '/^$/ d' | sort | uniq | tr '\n' ' ')" + aptconfig dump --no-empty --format '%v%n' APT::Architecture APT::Architectures | sort -u | tr '\n' ' ' } getarchitecturesfromcommalist() { diff --git a/test/integration/test-00-commands-have-help b/test/integration/test-00-commands-have-help index ebf8b8cfa..bbd1475eb 100755 --- a/test/integration/test-00-commands-have-help +++ b/test/integration/test-00-commands-have-help @@ -50,3 +50,14 @@ done for CMD in 'apt-dump-solver' 'apt-internal-solver'; do checkoptions "$(echo "$CMD" | tr -d '-')" done + +# in times of need, we all look for super cow to save the day +testsuccess aptget moo +testsuccess aptget moo -q=2 +testsuccess aptget moo moo +testsuccess aptget moo moo -q=2 +testsuccess aptget moo moo --color +testsuccess aptget moo moo moo +testsuccess aptget moo moo moo -q=2 +testsuccess aptget moo moo moo moo +testsuccess aptget moo moo moo moo -q=2 diff --git a/test/integration/test-apt-cache b/test/integration/test-apt-cache new file mode 100755 index 000000000..f47c0e08b --- /dev/null +++ b/test/integration/test-apt-cache @@ -0,0 +1,124 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework + +setupenvironment +configarchitecture 'amd64' 'i386' + +DESCR='Some description + That has multiple lines' +insertpackage 'unstable' 'fancy' 'all' '1' +insertpackage 'unstable,installed' 'foo' 'all' '1' 'Depends: bar +Conflicts: foobar +Recommends: cool (>= 2) | cooler (<< 5)' "$DESCR" +insertpackage 'unstable' 'bar' 'all' '1' 'Depends: bar +Breaks: foo (<< 1) +Replaces: foo (<< 1)' "$DESCR" + +setupaptarchive + +# dpkg is installed by our framework +testdpkginstalled 'dpkg' +testempty aptcache unmet dpkg + +# FIXME: Find some usecase for unmet as it seems kinda useless/broken +#testsuccess aptcache unmet +#testsuccess aptcache unmet foo + +# not too useful to test, but makes coverage green… +testsuccess aptcache stats +cp rootdir/tmp/testsuccess.output stats.output +testsuccess test -s stats.output +testsuccess aptcache xvcg foo +cp rootdir/tmp/testsuccess.output xvcg.output +testsuccess test -s xvcg.output +testsuccess aptcache dotty foo +cp rootdir/tmp/testsuccess.output dotty.output +testsuccess test -s dotty.output +# for this, even the sourcecode says it is useless (expect debugging) +testsuccess aptcache dump +cp rootdir/tmp/testsuccess.output dump.output +testsuccess test -s dump.output + +testequal 'dpkg +bar +fancy +foo' aptcache pkgnames +testequal 'bar' aptcache pkgnames bar +testequal 'fancy +foo' aptcache pkgnames f + +testequal " foo | 1 | file:$(readlink -f .)/aptarchive/ unstable/main amd64 Packages" aptcache madison foo + +### depends + +testequal 'foo + Depends: bar + |Recommends: + Recommends: + Conflicts: + Conflicts: ' aptcache depends foo +testequal 'foo + Depends: bar + Recommends: + Conflicts: + Conflicts: ' aptcache depends foo -o APT::Cache::ShowOnlyFirstOr=1 +testequal 'foo + Depends: bar + |Recommends: (>= 2) + Recommends: (<< 5) + Conflicts: + Conflicts: ' aptcache depends foo -o APT::Cache::ShowVersion=1 +testequal 'foo + Depends: bar + Conflicts: + Conflicts: ' aptcache depends foo --no-recommends +testequal 'foo + Depends: bar' aptcache depends foo --important +testequal 'foo + Conflicts: + Conflicts: ' aptcache depends foo --important --no-depends --conflicts +testequal 'foo + Depends: bar + |Recommends: + Recommends: + Conflicts: + Conflicts: +bar + Depends: bar + Breaks: foo + Breaks: + Replaces: foo + Replaces: + + + + +' aptcache depends foo --recurse +testequal 'foo + Depends: bar +bar + Depends: bar + Replaces: foo + Replaces: +' aptcache depends foo --recurse --important --replaces + +## rdpends + +testequal 'foo +Reverse Depends: + bar + bar' aptcache rdepends foo +testequal 'foo +Reverse Depends: + Replaces: bar + Breaks: bar' aptcache rdepends foo -o APT::Cache::ShowDependencyType=1 +testequal 'foo +Reverse Depends: + Replaces: bar (<< 1) + Breaks: bar (<< 1)' aptcache rdepends foo -o APT::Cache::ShowDependencyType=1 -o APT::Cache::ShowVersion=1 +testequal 'foo +Reverse Depends: + Breaks: bar (<< 1)' aptcache rdepends foo -o APT::Cache::ShowDependencyType=1 -o APT::Cache::ShowVersion=1 --important --breaks diff --git a/test/integration/test-apt-cli-search b/test/integration/test-apt-cli-search index 8f009d57c..1a28ba4da 100755 --- a/test/integration/test-apt-cli-search +++ b/test/integration/test-apt-cli-search @@ -25,6 +25,9 @@ setupaptarchive APTARCHIVE=$(readlink -f ./aptarchive) +testequal 'E: You must give at least one search pattern' aptcache search +testequal 'E: You must give at least one search pattern' apt search + # with OP progress testequal "Sorting... Full Text Search... diff --git a/test/integration/test-apt-cli-show b/test/integration/test-apt-cli-show index 4c8e134d6..930e591e0 100755 --- a/test/integration/test-apt-cli-show +++ b/test/integration/test-apt-cli-show @@ -36,3 +36,14 @@ APT-Sources: file:$APTARCHIVE/ unstable/main i386 Packages Description: Some description That has multiple lines " apt show foo + +# this is the default, but disabled by the testcases +testsuccess apt show foo -o Apt::Cmd::Disable-Script-Warning=0 +cp rootdir/tmp/testsuccess.output aptshow.output +testsuccess grep '^WARNING: ' aptshow.output + +if [ "$(id -u)" != '0' ]; then + testsuccess apt install foo -s -o APT::Get::Show-User-Simulation-Note=1 + cp rootdir/tmp/testsuccess.output aptshow.output + testsuccess grep '^NOTE: ' aptshow.output +fi diff --git a/test/integration/test-apt-cli-update b/test/integration/test-apt-cli-update index 987bb9adb..83cc94b93 100755 --- a/test/integration/test-apt-cli-update +++ b/test/integration/test-apt-cli-update @@ -8,10 +8,17 @@ setupenvironment configarchitecture "i386" insertpackage 'unstable' 'foo' 'all' '2.0' +cp rootdir/var/lib/dpkg/status dpkg.status insertinstalledpackage 'foo' 'all' '1.0' setupaptarchive --no-update APTARCHIVE=$(readlink -f ./aptarchive) +testequal 'E: The update command takes no arguments' apt update -q arguments + testequal "1 package can be upgraded. Run 'apt list --upgradable' to see it." apt update -q + +cp dpkg.status rootdir/var/lib/dpkg/status +insertinstalledpackage 'foo' 'all' '2.0' +testequal 'All packages are up to date.' apt update -q diff --git a/test/integration/test-apt-config b/test/integration/test-apt-config new file mode 100755 index 000000000..2f2ff9d38 --- /dev/null +++ b/test/integration/test-apt-config @@ -0,0 +1,36 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework + +setupenvironment +configarchitecture 'amd64' + +testsuccess aptconfig dump +testequal 'APT::Architecture "amd64";' aptconfig dump APT::Architecture +testempty aptconfig dump config::which::does::not::exist + +testequal 'APT::Architectures ""; +APT::Architectures:: "amd64";' aptconfig dump APT::Architectures +testequal 'APT::Architectures:: "amd64";' aptconfig dump --no-empty APT::Architectures +testequal 'amd64' aptconfig dump --no-empty --format='%v%n' APT::Architectures + +testempty aptconfig shell +testequal 'E: Arguments not in pairs' aptconfig shell APT::Architecture +testempty aptconfig shell APT::Architecture ARCH # incorrect order +testequal "ARCH='amd64'" aptconfig shell ARCH APT::Architecture + +ROOTDIR="$(readlink -f rootdir)" +testequal "CONFIG='apt.conf'" aptconfig shell CONFIG Dir::Etc::main +testequal "CONFIG='${ROOTDIR}/etc/apt/apt.conf'" aptconfig shell CONFIG Dir::Etc::main/f +testequal "CONFIG='etc/apt/'" aptconfig shell CONFIG Dir::Etc +testequal "CONFIG='${ROOTDIR}/etc/apt/'" aptconfig shell CONFIG Dir::Etc/ # old style +testequal "CONFIG='${ROOTDIR}/etc/apt/'" aptconfig shell CONFIG Dir::Etc/d + +testempty aptconfig dump --no-empty --format='%v%n' APT::Build-Profiles +export DEB_BUILD_PROFILES='nodoc stage1' +testequal 'nodoc +stage1' aptconfig dump --no-empty --format='%v%n' APT::Build-Profiles +unset DEB_BUILD_PROFILES +testempty aptconfig dump --no-empty --format='%v%n' APT::Build-Profiles diff --git a/test/integration/test-apt-helper b/test/integration/test-apt-helper index 06e497ff7..3c1d393a6 100755 --- a/test/integration/test-apt-helper +++ b/test/integration/test-apt-helper @@ -53,7 +53,7 @@ echo "http://some-proxy" EOF chmod 755 apt-proxy-detect echo "Acquire::http::Proxy-Auto-Detect \"$(pwd)/apt-proxy-detect\";" > rootdir/etc/apt/apt.conf.d/02proxy-detect - + testequal "Using proxy 'http://some-proxy' for URL 'http://www.example.com/'" apthelper auto-detect-proxy http://www.example.com @@ -64,13 +64,15 @@ echo "https://https-proxy" EOF chmod 755 apt-proxy-detect echo "Acquire::https::Proxy-Auto-Detect \"$(pwd)/apt-proxy-detect\";" > rootdir/etc/apt/apt.conf.d/02proxy-detect - - testequal "Using proxy 'https://https-proxy' for URL 'https://ssl.example.com/'" apthelper auto-detect-proxy https://ssl.example.com - - + testequal "Using proxy 'https://https-proxy' for URL 'https://ssl.example.com/'" apthelper auto-detect-proxy https://ssl.example.com } test_apt_helper_download test_apt_helper_detect_proxy +# test failure modes +testequal 'E: Invalid operation download' apthelper download +testequal 'E: Must specify at least one pair url/filename' apthelper download-file +testequal 'E: Must specify at least one pair url/filename' apthelper download-file http://example.org/ +testequal 'E: Need one URL as argument' apthelper auto-detect-proxy diff --git a/test/integration/test-apt-mark b/test/integration/test-apt-mark index 69e0f933d..0f62a12b4 100755 --- a/test/integration/test-apt-mark +++ b/test/integration/test-apt-mark @@ -20,21 +20,31 @@ testdpkginstalled dpkg testnoautopkg() { testempty aptmark showauto + testempty aptcache showauto testequal 'bar dpkg foo' aptmark showmanual testequal 'bar foo' aptmark showmanual bar foo uninstalled } -testmarkonpkgasauto() { - testsuccess aptmark $1 foo +testfooisauto() { testequal 'foo' aptmark showauto + testequal 'foo' aptcache showauto testequal 'foo' aptmark showauto foo + testequal 'foo' aptcache showauto foo testequal 'bar dpkg' aptmark showmanual testequal 'bar' aptmark showmanual bar +} +testmarkonpkgasauto() { + testsuccess $1 $2 foo + testfooisauto + testsuccess $1 $2 foo + testfooisauto - testsuccess aptmark $2 foo + testsuccess $1 $3 foo + testnoautopkg + testsuccess $1 $3 foo testnoautopkg } @@ -42,8 +52,9 @@ testequal 'E: No packages found' aptmark auto testequal 'E: No packages found' aptmark manual testnoautopkg -testmarkonpkgasauto 'auto' 'manual' -testmarkonpkgasauto 'markauto' 'unmarkauto' +testmarkonpkgasauto 'aptmark' 'auto' 'manual' +testmarkonpkgasauto 'aptmark' 'markauto' 'unmarkauto' +testmarkonpkgasauto 'aptget' 'markauto' 'unmarkauto' testnoholdpkg() { testempty aptmark showhold @@ -51,10 +62,19 @@ testnoholdpkg() { testempty aptmark showhold dpkg testempty aptmark showholds dpkg } -testmarkonepkgashold() { - testsuccess aptmark hold $1 +testpkgonhold() { testequal "$1" aptmark showhold testequal "$1" aptmark showholds + testequal "$1" aptmark showhold $1 + testequal "$1" aptmark showholds $1 +} +testmarkonepkgashold() { + testsuccess aptmark hold $1 + testpkgonhold $1 + testsuccess aptmark hold $1 + testpkgonhold $1 + testsuccess aptmark unhold $1 + testnoholdpkg testsuccess aptmark unhold $1 testnoholdpkg } diff --git a/test/integration/test-apt-update-stale b/test/integration/test-apt-update-stale index 52f94591f..277aa5b09 100755 --- a/test/integration/test-apt-update-stale +++ b/test/integration/test-apt-update-stale @@ -14,9 +14,11 @@ configarchitecture "i386" insertpackage 'unstable' 'foo' 'all' '1.0' -setupaptarchive +setupaptarchive --no-update changetowebserver -aptget update -qq + +echo "Acquire::Languages \"none\";" > rootdir/etc/apt/apt.conf.d/00nolanguages +testsuccess aptget update listcurrentlistsdirectory > lists.before # insert new version diff --git a/test/integration/test-external-dependency-solver-protocol b/test/integration/test-external-dependency-solver-protocol index 07d2441b6..fd68578c5 100755 --- a/test/integration/test-external-dependency-solver-protocol +++ b/test/integration/test-external-dependency-solver-protocol @@ -12,7 +12,10 @@ insertinstalledpackage 'stuff' 'all' '1' insertpackage 'unstable' 'cool' 'all' '2' 'Multi-Arch: foreign' insertpackage 'unstable' 'stuff' 'all' '2' 'Multi-Arch: foreign' insertpackage 'unstable' 'coolstuff' 'i386,amd64' '2' 'Depends: cool, stuff' -insertpackage 'unstable' 'awesome' 'all' '2' 'Multi-Arch: foreign' +insertpackage 'unstable' 'awesome' 'all' '2' 'Multi-Arch: foreign +Conflicts: badstuff' +insertpackage 'unstable' 'badstuff' 'all' '2' 'Multi-Arch: foreign +Conflicts: awesome' insertpackage 'unstable' 'awesomecoolstuff' 'i386' '2' 'Depends: coolstuff, awesome' insertpackage 'experimental' 'cool' 'all' '3' 'Multi-Arch: foreign' @@ -44,6 +47,14 @@ The following NEW packages will be installed: Inst coolstuff (3 experimental [amd64]) Conf coolstuff (3 experimental [amd64])' aptget install --solver apt coolstuff -s +testequal 'Reading package lists... +Building dependency tree... +Execute external solver... +The following packages will be REMOVED: + cool* +0 upgraded, 0 newly installed, 1 to remove and 1 not upgraded. +Purg cool [1]' aptget purge --solver apt cool -s + testsuccess aptget install awesomecoolstuff:i386 -s testsuccess aptget install --solver apt awesomecoolstuff:i386 -s @@ -57,9 +68,13 @@ testsuccess aptget dist-upgrade -s --solver apt testsuccess aptget upgrade -s testsuccess aptget upgrade -s --solver apt +testfailure aptget install awesome badstuff -s +testfailure aptget install awesome badstuff -s --solver apt +testsuccess grep 'ERR_UNSOLVABLE' rootdir/tmp/testfailure.output + configarchitecture 'armel' msgtest 'Test direct calling is okay for' 'apt-internal-solver' -cat /tmp/dump.edsp | aptinternalsolver > solver.result 2>&1 || true +cat /tmp/dump.edsp | aptinternalsolver -q=0 > solver.result 2>&1 || true if [ "$(tail -n2 solver.result | head -n1 )" = "Message: Done" ]; then msgpass else @@ -69,3 +84,16 @@ fi rm -f /tmp/dump.edsp testfailure aptget install --solver apt awesomecoolstuff:i386 -s + +testsuccess aptinternalsolver scenario +testequal 'Package: stuff +Source: stuff +Architecture: all +Version: 1 +Installed: yes +APT-ID: 2 +Priority: optional +Section: other +APT-Pin: 100 +APT-Candidate: yes +' aptinternalsolver scenario stuff -- cgit v1.2.3-70-g09d2 From 8fe964f148344b8a55252fe52b6292a4ab86ea98 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 14 Nov 2014 18:01:09 +0100 Subject: create our cache and lib directory always with mode 755 We autocreate for a while now the last two directories in /var/lib/apt/lists (similar for /var/cache/apt/archives) which is very nice for systems having any of those on tmpfs or other non-persistent storage. This also means though that this creation is effected by the default umask, so for people with aggressive umasks like 027 the directories will be created with 750, which means all non-root users are left out, which is usually exactly what we want then this umask is set, but the cache and lib directories contain public knowledge. There isn't any need to protect them from viewers and they render apt completely useless if not readable. --- apt-pkg/acquire.cc | 7 +++++-- apt-pkg/cdrom.cc | 7 +++++-- test/integration/framework | 24 ++++++++++++++++++++++-- test/integration/test-apt-cdrom | 1 - test/integration/test-apt-update-transactions | 6 +----- 5 files changed, 33 insertions(+), 12 deletions(-) (limited to 'test/integration/framework') diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index 07c4646f5..0c815c005 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -92,8 +92,11 @@ void pkgAcquire::Initialize() static bool SetupAPTPartialDirectory(std::string const &grand, std::string const &parent) { std::string const partial = parent + "partial"; - if (CreateAPTDirectoryIfNeeded(grand, partial) == false && - CreateAPTDirectoryIfNeeded(parent, partial) == false) + mode_t const mode = umask(S_IWGRP | S_IWOTH); + bool const creation_fail = (CreateAPTDirectoryIfNeeded(grand, partial) == false && + CreateAPTDirectoryIfNeeded(parent, partial) == false); + umask(mode); + if (creation_fail == true) return false; std::string const SandboxUser = _config->Find("APT::Sandbox::User"); diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc index b97f7b036..aaa7b82e0 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -822,8 +822,11 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ // check for existence and possibly create state directory for copying string const listDir = _config->FindDir("Dir::State::lists"); string const partialListDir = listDir + "partial/"; - if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), partialListDir) == false && - CreateAPTDirectoryIfNeeded(listDir, partialListDir) == false) + mode_t const mode = umask(S_IWGRP | S_IWOTH); + bool const creation_fail = (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), partialListDir) == false && + CreateAPTDirectoryIfNeeded(listDir, partialListDir) == false); + umask(mode); + if (creation_fail == true) { UnmountCDROM(CDROM, NULL); return _error->Errno("cdrom", _("List directory %spartial is missing."), listDir.c_str()); diff --git a/test/integration/framework b/test/integration/framework index c9f62c141..191e205ce 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -203,7 +203,7 @@ 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/apt var/log tmp + mkdir -p usr/bin var/cache var/lib var/log tmp mkdir -p var/lib/dpkg/info var/lib/dpkg/updates var/lib/dpkg/triggers touch var/lib/dpkg/available mkdir -p usr/lib/apt @@ -1341,7 +1341,7 @@ testfilestats() { msgpass else echo >&2 - ls -l >&2 "$1" + ls -ld >&2 "$1" echo -n >&2 "stat(1) reports for $2: " stat --format "$2" "$1" msgfail @@ -1386,6 +1386,24 @@ listcurrentlistsdirectory() { done } +### convinience 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 + # 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" + command mkdir -m 700 -p "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial" + touch "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/lock" + if [ "$(id -u)" = '0' ]; then + chown _apt:root "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial" + fi + else + command mkdir "$@" + fi +} + ### The following tests are run by most test methods automatically to check ### general things about commands executed without writing the test every time. @@ -1410,6 +1428,8 @@ aptautotest() { aptautotest_aptget_update() { if ! test -d "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists"; then return; fi + testfilestats "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt" '%U:%G:%a' '=' "${USER}:${USER}:755" + testfilestats "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" '%U:%G:%a' '=' "${USER}:${USER}:755" # all copied files are properly chmodded for file in $(find "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" -maxdepth 1 -type f ! -name 'lock'); do testfilestats "$file" '%U:%G:%a' '=' "${USER}:${USER}:644" diff --git a/test/integration/test-apt-cdrom b/test/integration/test-apt-cdrom index 3a33219fe..7da645e83 100755 --- a/test/integration/test-apt-cdrom +++ b/test/integration/test-apt-cdrom @@ -125,7 +125,6 @@ $CDROM_POST" aptcdromlog add msgtest 'Test for the german description translation of' 'testing' aptcache show testing -o Acquire::Languages=de | grep -q '^Description-de: ' && msgpass || msgfail rm -rf rootdir/var/lib/apt/lists -mkdir -p rootdir/var/lib/apt/lists/partial testequal "$CDROM_PRE Found 2 package indexes, 1 source indexes, 1 translation indexes and 1 signatures $CDROM_POST" aptcdromlog add diff --git a/test/integration/test-apt-update-transactions b/test/integration/test-apt-update-transactions index bf425a22e..b325733ac 100755 --- a/test/integration/test-apt-update-transactions +++ b/test/integration/test-apt-update-transactions @@ -48,11 +48,7 @@ testrun() { testsetup() { msgmsg 'Test with no initial data over' "$1" rm -rf rootdir/var/lib/apt/lists - mkdir -m 700 -p rootdir/var/lib/apt/lists/partial - touch rootdir/var/lib/apt/lists/lock - if [ "$(id -u)" = '0' ]; then - chown _apt:root rootdir/var/lib/apt/lists/partial - fi + mkdir -p rootdir/var/lib/apt/lists/partial listcurrentlistsdirectory > listsdir.lst testrun 'listsdir.lst' -- cgit v1.2.3-70-g09d2 From 4bb006d1ddcf1807474067dcbef9fb0bb5def0ac Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 17 Nov 2014 22:54:29 +0100 Subject: fix file ownership tests to work on kfreebsd While on linux files are created in /tmp with $USER:$USER, on my kfreebsd testmachine they are created with $USER:root, so we pull some strings here to make it work on both. --- test/integration/framework | 14 +++++++++++--- test/integration/test-apt-cdrom | 2 +- test/integration/test-apt-get-changelog | 4 ++-- test/integration/test-apt-get-source-authenticated | 1 - test/integration/test-authentication-basic | 4 ++-- 5 files changed, 16 insertions(+), 9 deletions(-) (limited to 'test/integration/framework') diff --git a/test/integration/framework b/test/integration/framework index 191e205ce..51c7b8cae 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -272,6 +272,14 @@ setupenvironment() { echo "Apt::Cmd::Disable-Script-Warning \"1\";" > rootdir/etc/apt/apt.conf.d/apt-binary configcompression '.' 'gz' #'bz2' 'lzma' 'xz' + # create some files in /tmp and look at user/group to get what this means + TEST_DEFAULT_USER="$USER" + if [ "$(uname)" = 'GNU/kFreeBSD' ]; then + TEST_DEFAULT_GROUP='root' + else + TEST_DEFAULT_GROUP="$USER" + fi + # Acquire::AllowInsecureRepositories=false is not yet the default # but we want it to be the default soon configallowinsecurerepositories "false"; @@ -1428,11 +1436,11 @@ aptautotest() { aptautotest_aptget_update() { if ! test -d "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists"; then return; fi - testfilestats "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt" '%U:%G:%a' '=' "${USER}:${USER}:755" - testfilestats "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" '%U:%G:%a' '=' "${USER}:${USER}:755" + testfilestats "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:755" + testfilestats "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:755" # all copied files are properly chmodded for file in $(find "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" -maxdepth 1 -type f ! -name 'lock'); do - testfilestats "$file" '%U:%G:%a' '=' "${USER}:${USER}:644" + testfilestats "$file" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644" done } aptautotest_apt_update() { aptautotest_aptget_update "$@"; } diff --git a/test/integration/test-apt-cdrom b/test/integration/test-apt-cdrom index 7da645e83..7f4b3c257 100755 --- a/test/integration/test-apt-cdrom +++ b/test/integration/test-apt-cdrom @@ -146,5 +146,5 @@ testcdromusage msgmsg 'Check that nothing touched our' 'CD-ROM' for file in $(find rootdir/media/cdrom-unmounted/dists); do - testfilestats "$file" '%U:%G:%a' '=' "${USER}:${USER}:555" + testfilestats "$file" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:555" done diff --git a/test/integration/test-apt-get-changelog b/test/integration/test-apt-get-changelog index 648dccf40..01f2bd393 100755 --- a/test/integration/test-apt-get-changelog +++ b/test/integration/test-apt-get-changelog @@ -33,7 +33,7 @@ testfileequal '../rootdir/tmp/testsuccess.output' "$(cat ../aptarchive/pool/apt_ testsuccess aptget changelog apt -d testfileequal 'apt.changelog' "$(cat ../aptarchive/pool/apt_1.0/changelog)" -testfilestats 'apt.changelog' '%U:%G:%a' '=' "${USER}:${USER}:644" +testfilestats 'apt.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644" rm -f apt.changelog ../aptarchive/pool/apt_1.0/changelog testequal "$(cat ../aptarchive/pool/apt_1.0.changelog)" aptget changelog apt \ @@ -41,7 +41,7 @@ testequal "$(cat ../aptarchive/pool/apt_1.0.changelog)" aptget changelog apt \ testsuccess aptget changelog apt -d testfileequal 'apt.changelog' "$(cat ../aptarchive/pool/apt_1.0.changelog)" -testfilestats 'apt.changelog' '%U:%G:%a' '=' "${USER}:${USER}:644" +testfilestats 'apt.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644" rm -f apt.changelog ../aptarchive/pool/apt_1.0.changelog testequal 'E: changelog download failed' aptget changelog apt -qq -d -o APT::Changelogs::Server='http://not-on-the-main-server:8080/' diff --git a/test/integration/test-apt-get-source-authenticated b/test/integration/test-apt-get-source-authenticated index f68c32386..685bc566b 100755 --- a/test/integration/test-apt-get-source-authenticated +++ b/test/integration/test-apt-get-source-authenticated @@ -31,4 +31,3 @@ testfailure test -e foo_2.0.dsc # allow overriding the warning testsuccess aptget source --allow-unauthenticated foo -o Debug::pkgAcquire::Worker=1 testsuccess test -s foo_2.0.dsc -a -L foo_2.0.dsc -testaccessrights 'foo_2.0.dsc' '777' diff --git a/test/integration/test-authentication-basic b/test/integration/test-authentication-basic index 21b024970..7e74726be 100755 --- a/test/integration/test-authentication-basic +++ b/test/integration/test-authentication-basic @@ -24,7 +24,7 @@ testauthfailure() { testauthsuccess() { testsuccess apthelper download-file "${1}/bash" ./downloaded/bash testfileequal ./downloaded/bash "$(cat aptarchive/bash)" - testfilestats ./downloaded/bash '%U:%G:%a' '=' "${USER}:${USER}:644" + testfilestats ./downloaded/bash '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644" rm -f ./downloaded/bash # lets see if got/retains acceptable permissions @@ -32,7 +32,7 @@ testauthsuccess() { if [ "$(id -u)" = '0' ]; then testfilestats "$AUTHCONF" '%U:%G:%a' '=' "_apt:root:600" else - testfilestats "$AUTHCONF" '%U:%G:%a' '=' "${USER}:${USER}:600" + testfilestats "$AUTHCONF" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:600" fi fi -- cgit v1.2.3-70-g09d2 From 0c78757010a17173bdc79b818133697e7dcbf6a4 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 17 Nov 2014 15:06:35 +0100 Subject: close leaking slave fd after setting up pty magic The fd moves out of scope here anyway, so we should close it properly instead of leaking it which will tickle down to dpkg maintainer scripts. Closes: 767774 --- apt-pkg/deb/dpkgpm.cc | 6 +- test/integration/framework | 71 ++++++++++++++++++---- test/integration/test-failing-maintainer-scripts | 46 +------------- .../test-no-fds-leaked-to-maintainer-scripts | 40 ++++++++++++ 4 files changed, 103 insertions(+), 60 deletions(-) create mode 100755 test/integration/test-no-fds-leaked-to-maintainer-scripts (limited to 'test/integration/framework') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 3f6039e0d..dd03eac2c 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1158,8 +1158,7 @@ void pkgDPkgPM::SetupSlavePtyMagic() int const slaveFd = open(d->slave, O_RDWR); if (slaveFd == -1) _error->FatalE("open", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); - - if (ioctl(slaveFd, TIOCSCTTY, 0) < 0) + else if (ioctl(slaveFd, TIOCSCTTY, 0) < 0) _error->FatalE("ioctl", "Setting TIOCSCTTY for slave fd %d failed!", slaveFd); else { @@ -1170,6 +1169,9 @@ void pkgDPkgPM::SetupSlavePtyMagic() if (tcsetattr(0, TCSANOW, &d->tt) < 0) _error->FatalE("tcsetattr", "Setting in Setup via TCSANOW for slave fd %d failed!", slaveFd); } + + if (slaveFd != -1) + close(slaveFd); } void pkgDPkgPM::StopPtyMagic() { diff --git a/test/integration/framework b/test/integration/framework index 51c7b8cae..ff059f59e 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -358,6 +358,54 @@ configdpkg() { fi } +configdpkgnoopchroot() { + # create a library to noop chroot() and rewrite maintainer script executions + # via execvp() as used by dpkg as we don't want our rootdir to be a fullblown + # chroot directory dpkg could chroot into to execute the maintainer scripts + msgtest 'Building library to preload to make maintainerscript work in' 'dpkg' + cat << EOF > noopchroot.c +#define _GNU_SOURCE +#include +#include +#include +#include + +static char * chrootdir = NULL; + +int chroot(const char *path) { + printf("WARNING: CHROOTing to %s was ignored!\n", path); + free(chrootdir); + chrootdir = strdup(path); + return 0; +} +int execvp(const char *file, char *const argv[]) { + static int (*func_execvp) (const char *, char * const []) = NULL; + if (func_execvp == NULL) + func_execvp = (int (*) (const char *, char * const [])) dlsym(RTLD_NEXT, "execvp"); + 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); + return func_execvp(newfile, argv); +} +EOF + testsuccess --nomsg gcc -fPIC -shared -o noopchroot.so noopchroot.c -ldl + + mkdir -p "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/" + DPKG="${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" + echo "#!/bin/sh +if [ -n \"\$LD_PRELOAD\" ]; then + export LD_PRELOAD=\"${TMPWORKINGDIRECTORY}/noopchroot.so \${LD_PRELOAD}\" +else + export LD_PRELOAD=\"${TMPWORKINGDIRECTORY}/noopchroot.so\" +fi +dpkg \"\$@\"" > $DPKG + chmod +x $DPKG + sed -ie "s|^DPKG::options:: \"dpkg\";\$|DPKG::options:: \"$DPKG\";|" aptconfig.conf +} + configallowinsecurerepositories() { echo "Acquire::AllowInsecureRepositories \"$1\";" > rootdir/etc/apt/apt.conf.d/allow-insecure-repositories.conf @@ -480,7 +528,7 @@ buildsimplenativepackage() { fi local BUILDDIR=${TMPWORKINGDIRECTORY}/incoming/${NAME}-${VERSION} - msgninfo "Build package ${NAME} in ${VERSION} for ${RELEASE} in ${DISTSECTION}… " + msgtest "Build source package in version ${VERSION} for ${RELEASE} in ${DISTSECTION}" "$NAME" mkdir -p $BUILDDIR/debian/source echo "* most suckless software product ever" > ${BUILDDIR}/FEATURES echo "#!/bin/sh @@ -512,7 +560,10 @@ Package: $NAME" >> ${BUILDDIR}/debian/control echo "Description: $DESCRIPTION" >> ${BUILDDIR}/debian/control echo '3.0 (native)' > ${BUILDDIR}/debian/source/format - (cd ${BUILDDIR}/..; dpkg-source -b ${NAME}-${VERSION} 2>&1) | sed -n 's#^dpkg-source: info: building [^ ]\+ in ##p' \ + cd ${BUILDDIR}/.. + testsuccess --nomsg dpkg-source -b ${NAME}-${VERSION} + cd - >/dev/null + sed -n 's#^dpkg-source: info: building [^ ]\+ in ##p' ${TMPWORKINGDIRECTORY}/rootdir/tmp/testsuccess.output \ | while read SRC; do echo "pool/${SRC}" >> ${BUILDDIR}/../${RELEASE}.${DISTSECTION}.srclist # if expr match "${SRC}" '.*\.dsc' >/dev/null 2>&1; then @@ -524,6 +575,7 @@ Package: $NAME" >> ${BUILDDIR}/debian/control done for arch in $(getarchitecturesfromcommalist "$ARCH"); do + msgtest "Build binary package for ${RELEASE} in ${SECTION}" "$NAME" rm -rf ${BUILDDIR}/debian/tmp mkdir -p ${BUILDDIR}/debian/tmp/DEBIAN ${BUILDDIR}/debian/tmp/usr/share/doc/${NAME} ${BUILDDIR}/debian/tmp/usr/bin cp ${BUILDDIR}/debian/copyright ${BUILDDIR}/debian/changelog ${BUILDDIR}/FEATURES ${BUILDDIR}/debian/tmp/usr/share/doc/${NAME} @@ -537,11 +589,7 @@ Package: $NAME" >> ${BUILDDIR}/debian/control local LOG="${BUILDDIR}/../${NAME}_${VERSION}_${arch}.dpkg-deb.log" # ensure the right permissions as dpkg-deb ensists chmod 755 ${BUILDDIR}/debian/tmp/DEBIAN - if ! dpkg-deb -Z${COMPRESS_TYPE} --build ${BUILDDIR}/debian/tmp ${BUILDDIR}/.. >$LOG 2>&1; then - cat $LOG - false - fi - rm $LOG + testsuccess --nomsg dpkg-deb -Z${COMPRESS_TYPE} --build ${BUILDDIR}/debian/tmp ${BUILDDIR}/.. echo "pool/${NAME}_${VERSION}_${arch}.deb" >> ${BUILDDIR}/../${RELEASE}.${DISTSECTION}.pkglist done @@ -559,15 +607,13 @@ buildpackage() { local ARCH=$(getarchitecture $4) local PKGNAME="$(echo "$BUILDDIR" | grep -o '[^/]*$')" local BUILDLOG="$(readlink -f "${BUILDDIR}/../${PKGNAME}_${RELEASE}_${SECTION}.dpkg-bp.log")" - msgninfo "Build package ${PKGNAME} for ${RELEASE} in ${SECTION}… " + msgtest "Build package for ${RELEASE} in ${SECTION}" "$PKGNAME" cd $BUILDDIR if [ "$ARCH" = "all" ]; then ARCH="$(dpkg-architecture -qDEB_HOST_ARCH 2> /dev/null)" fi - if ! dpkg-buildpackage -uc -us -a$ARCH >$BUILDLOG 2>&1 ; then - cat $BUILDLOG - false - fi + testsuccess --nomsg dpkg-buildpackage -uc -us -a$ARCH + cp ${TMPWORKINGDIRECTORY}/rootdir/tmp/testsuccess.output $BUILDLOG local PKGS="$(grep '^dpkg-deb: building package' $BUILDLOG | cut -d'/' -f 2 | sed -e "s#'\.##")" local SRCS="$(grep '^dpkg-source: info: building' $BUILDLOG | grep -o '[a-z0-9._+~-]*$')" cd - > /dev/null @@ -577,7 +623,6 @@ buildpackage() { for SRC in $SRCS; do echo "pool/${SRC}" >> ${TMPWORKINGDIRECTORY}/incoming/${RELEASE}.${SECTION}.srclist done - msgdone "info" } buildaptarchive() { diff --git a/test/integration/test-failing-maintainer-scripts b/test/integration/test-failing-maintainer-scripts index 3dd7d643e..953506aa5 100755 --- a/test/integration/test-failing-maintainer-scripts +++ b/test/integration/test-failing-maintainer-scripts @@ -6,6 +6,7 @@ TESTDIR=$(readlink -f $(dirname $0)) setupenvironment configarchitecture 'native' +configdpkgnoopchroot # create a bunch of failures createfailure() { @@ -25,51 +26,6 @@ createfailure 'postrm' setupaptarchive -# create a library to noop chroot() and rewrite maintainer script executions -# via execvp() as used by dpkg as we don't want our rootdir to be a fullblown -# chroot directory dpkg could chroot into to execute the maintainer scripts -cat << EOF > noopchroot.c -#define _GNU_SOURCE -#include -#include -#include -#include - -static char * chrootdir = NULL; - -int chroot(const char *path) { - printf("WARNING: CHROOTing to %s was ignored!\n", path); - free(chrootdir); - chrootdir = strdup(path); - return 0; -} -int execvp(const char *file, char *const argv[]) { - static int (*func_execvp) (const char *, char * const []) = NULL; - if (func_execvp == NULL) - func_execvp = (int (*) (const char *, char * const [])) dlsym(RTLD_NEXT, "execvp"); - 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); - return func_execvp(newfile, argv); -} -EOF -testsuccess gcc -fPIC -shared -o noopchroot.so noopchroot.c -ldl - -mkdir -p "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/" -DPKG="${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" -echo "#!/bin/sh -if [ -n \"\$LD_PRELOAD\" ]; then - export LD_PRELOAD=\"${TMPWORKINGDIRECTORY}/noopchroot.so \${LD_PRELOAD}\" -else - export LD_PRELOAD=\"${TMPWORKINGDIRECTORY}/noopchroot.so\" -fi -dpkg \"\$@\"" > $DPKG -chmod +x $DPKG -sed -ie "s|^DPKG::options:: \"dpkg\";\$|DPKG::options:: \"$DPKG\";|" aptconfig.conf - # setup some pre- and post- invokes to check the output isn't garbled later APTHOOK="${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apthook" echo '#!/bin/sh diff --git a/test/integration/test-no-fds-leaked-to-maintainer-scripts b/test/integration/test-no-fds-leaked-to-maintainer-scripts new file mode 100755 index 000000000..6ed120090 --- /dev/null +++ b/test/integration/test-no-fds-leaked-to-maintainer-scripts @@ -0,0 +1,40 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework + +setupenvironment +configarchitecture 'native' +configdpkgnoopchroot + +setupsimplenativepackage "fdleaks" 'native' '1.0' 'unstable' +BUILDDIR="incoming/fdleaks-1.0" +for script in 'preinst' 'postinst' 'prerm' 'postrm'; do + echo '#!/bin/sh +ls -l /proc/self/fd/' > ${BUILDDIR}/debian/$script +done +buildpackage "$BUILDDIR" 'unstable' 'main' 'native' +rm -rf "$BUILDDIR" + +setupaptarchive + +testsuccess aptget install -y fdleaks +msgtest 'Check if fds were not' 'leaked' +if [ "$(grep 'root root' rootdir/tmp/testsuccess.output | wc -l)" = '8' ]; then + msgpass +else + echo + cat rootdir/tmp/testsuccess.output + msgfail +fi + +testsuccess aptget purge -y fdleaks +msgtest 'Check if fds were not' 'leaked' +if [ "$(grep 'root root' rootdir/tmp/testsuccess.output | wc -l)" = '12' ]; then + msgpass +else + echo + cat rootdir/tmp/testsuccess.output + msgfail +fi -- cgit v1.2.3-70-g09d2 From 9fc0b435593839de47098212f0ae5f15b6263099 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 17 Nov 2014 15:06:35 +0100 Subject: close leaking slave fd after setting up pty magic The fd moves out of scope here anyway, so we should close it properly instead of leaking it which will tickle down to dpkg maintainer scripts. Closes: 767774 --- apt-pkg/deb/dpkgpm.cc | 6 +- test/integration/framework | 78 ++++++++++++++++++---- test/integration/test-failing-maintainer-scripts | 46 +------------ .../test-no-fds-leaked-to-maintainer-scripts | 40 +++++++++++ 4 files changed, 109 insertions(+), 61 deletions(-) create mode 100755 test/integration/test-no-fds-leaked-to-maintainer-scripts (limited to 'test/integration/framework') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 7bbf18cba..e1f1ec680 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1160,8 +1160,7 @@ void pkgDPkgPM::SetupSlavePtyMagic() int const slaveFd = open(d->slave, O_RDWR); if (slaveFd == -1) _error->FatalE("open", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); - - if (ioctl(slaveFd, TIOCSCTTY, 0) < 0) + else if (ioctl(slaveFd, TIOCSCTTY, 0) < 0) _error->FatalE("ioctl", "Setting TIOCSCTTY for slave fd %d failed!", slaveFd); else { @@ -1172,6 +1171,9 @@ void pkgDPkgPM::SetupSlavePtyMagic() if (tcsetattr(0, TCSANOW, &d->tt) < 0) _error->FatalE("tcsetattr", "Setting in Setup via TCSANOW for slave fd %d failed!", slaveFd); } + + if (slaveFd != -1) + close(slaveFd); } void pkgDPkgPM::StopPtyMagic() { diff --git a/test/integration/framework b/test/integration/framework index 7923e23d9..df1942ff9 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -325,6 +325,59 @@ configdpkg() { fi } +configdpkgnoopchroot() { + # create a library to noop chroot() and rewrite maintainer script executions + # via execvp() as used by dpkg as we don't want our rootdir to be a fullblown + # chroot directory dpkg could chroot into to execute the maintainer scripts + msgtest 'Building library to preload to make maintainerscript work in' 'dpkg' + cat << EOF > noopchroot.c +#define _GNU_SOURCE +#include +#include +#include +#include + +static char * chrootdir = NULL; + +int chroot(const char *path) { + printf("WARNING: CHROOTing to %s was ignored!\n", path); + free(chrootdir); + chrootdir = strdup(path); + return 0; +} +int execvp(const char *file, char *const argv[]) { + static int (*func_execvp) (const char *, char * const []) = NULL; + if (func_execvp == NULL) + func_execvp = (int (*) (const char *, char * const [])) dlsym(RTLD_NEXT, "execvp"); + 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); + return func_execvp(newfile, argv); +} +EOF + testsuccess --nomsg gcc -fPIC -shared -o noopchroot.so noopchroot.c -ldl + + mkdir -p "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/" + DPKG="${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" + echo "#!/bin/sh +if [ -n \"\$LD_PRELOAD\" ]; then + export LD_PRELOAD=\"${TMPWORKINGDIRECTORY}/noopchroot.so \${LD_PRELOAD}\" +else + export LD_PRELOAD=\"${TMPWORKINGDIRECTORY}/noopchroot.so\" +fi +dpkg \"\$@\"" > $DPKG + chmod +x $DPKG + sed -ie "s|^DPKG::options:: \"dpkg\";\$|DPKG::options:: \"$DPKG\";|" aptconfig.conf +} + +configallowinsecurerepositories() { + echo "Acquire::AllowInsecureRepositories \"$1\";" > rootdir/etc/apt/apt.conf.d/allow-insecure-repositories.conf + +} + configcompression() { while [ -n "$1" ]; do case "$1" in @@ -442,7 +495,7 @@ buildsimplenativepackage() { fi local BUILDDIR=${TMPWORKINGDIRECTORY}/incoming/${NAME}-${VERSION} - msgninfo "Build package ${NAME} in ${VERSION} for ${RELEASE} in ${DISTSECTION}… " + msgtest "Build source package in version ${VERSION} for ${RELEASE} in ${DISTSECTION}" "$NAME" mkdir -p $BUILDDIR/debian/source echo "* most suckless software product ever" > ${BUILDDIR}/FEATURES echo "#!/bin/sh @@ -474,7 +527,10 @@ Package: $NAME" >> ${BUILDDIR}/debian/control echo "Description: $DESCRIPTION" >> ${BUILDDIR}/debian/control echo '3.0 (native)' > ${BUILDDIR}/debian/source/format - (cd ${BUILDDIR}/..; dpkg-source -b ${NAME}-${VERSION} 2>&1) | sed -n 's#^dpkg-source: info: building [^ ]\+ in ##p' \ + cd ${BUILDDIR}/.. + testsuccess --nomsg dpkg-source -b ${NAME}-${VERSION} + cd - >/dev/null + sed -n 's#^dpkg-source: info: building [^ ]\+ in ##p' ${TMPWORKINGDIRECTORY}/rootdir/tmp/testsuccess.output \ | while read SRC; do echo "pool/${SRC}" >> ${BUILDDIR}/../${RELEASE}.${DISTSECTION}.srclist # if expr match "${SRC}" '.*\.dsc' >/dev/null 2>&1; then @@ -486,6 +542,7 @@ Package: $NAME" >> ${BUILDDIR}/debian/control done for arch in $(getarchitecturesfromcommalist "$ARCH"); do + msgtest "Build binary package for ${RELEASE} in ${SECTION}" "$NAME" rm -rf ${BUILDDIR}/debian/tmp mkdir -p ${BUILDDIR}/debian/tmp/DEBIAN ${BUILDDIR}/debian/tmp/usr/share/doc/${NAME} ${BUILDDIR}/debian/tmp/usr/bin cp ${BUILDDIR}/debian/copyright ${BUILDDIR}/debian/changelog ${BUILDDIR}/FEATURES ${BUILDDIR}/debian/tmp/usr/share/doc/${NAME} @@ -499,11 +556,7 @@ Package: $NAME" >> ${BUILDDIR}/debian/control local LOG="${BUILDDIR}/../${NAME}_${VERSION}_${arch}.dpkg-deb.log" # ensure the right permissions as dpkg-deb ensists chmod 755 ${BUILDDIR}/debian/tmp/DEBIAN - if ! dpkg-deb -Z${COMPRESS_TYPE} --build ${BUILDDIR}/debian/tmp ${BUILDDIR}/.. >$LOG 2>&1; then - cat $LOG - false - fi - rm $LOG + testsuccess --nomsg dpkg-deb -Z${COMPRESS_TYPE} --build ${BUILDDIR}/debian/tmp ${BUILDDIR}/.. echo "pool/${NAME}_${VERSION}_${arch}.deb" >> ${BUILDDIR}/../${RELEASE}.${DISTSECTION}.pkglist done @@ -521,15 +574,13 @@ buildpackage() { local ARCH=$(getarchitecture $4) local PKGNAME="$(echo "$BUILDDIR" | grep -o '[^/]*$')" local BUILDLOG="$(readlink -f "${BUILDDIR}/../${PKGNAME}_${RELEASE}_${SECTION}.dpkg-bp.log")" - msgninfo "Build package ${PKGNAME} for ${RELEASE} in ${SECTION}… " + msgtest "Build package for ${RELEASE} in ${SECTION}" "$PKGNAME" cd $BUILDDIR if [ "$ARCH" = "all" ]; then ARCH="$(dpkg-architecture -qDEB_HOST_ARCH 2> /dev/null)" fi - if ! dpkg-buildpackage -uc -us -a$ARCH >$BUILDLOG 2>&1 ; then - cat $BUILDLOG - false - fi + testsuccess --nomsg dpkg-buildpackage -uc -us -a$ARCH + cp ${TMPWORKINGDIRECTORY}/rootdir/tmp/testsuccess.output $BUILDLOG local PKGS="$(grep '^dpkg-deb: building package' $BUILDLOG | cut -d'/' -f 2 | sed -e "s#'\.##")" local SRCS="$(grep '^dpkg-source: info: building' $BUILDLOG | grep -o '[a-z0-9._+~-]*$')" cd - > /dev/null @@ -539,7 +590,6 @@ buildpackage() { for SRC in $SRCS; do echo "pool/${SRC}" >> ${TMPWORKINGDIRECTORY}/incoming/${RELEASE}.${SECTION}.srclist done - msgdone "info" } buildaptarchive() { @@ -1072,7 +1122,7 @@ testequal() { if [ -n "$MSG" ]; then msgtest "$MSG" "$*" fi - $* 2>&1 | checkdiff $COMPAREFILE - && msgpass || msgfail + "$@" 2>&1 | checkdiff $COMPAREFILE - && msgpass || msgfail } testequalor2() { diff --git a/test/integration/test-failing-maintainer-scripts b/test/integration/test-failing-maintainer-scripts index 3dd7d643e..953506aa5 100755 --- a/test/integration/test-failing-maintainer-scripts +++ b/test/integration/test-failing-maintainer-scripts @@ -6,6 +6,7 @@ TESTDIR=$(readlink -f $(dirname $0)) setupenvironment configarchitecture 'native' +configdpkgnoopchroot # create a bunch of failures createfailure() { @@ -25,51 +26,6 @@ createfailure 'postrm' setupaptarchive -# create a library to noop chroot() and rewrite maintainer script executions -# via execvp() as used by dpkg as we don't want our rootdir to be a fullblown -# chroot directory dpkg could chroot into to execute the maintainer scripts -cat << EOF > noopchroot.c -#define _GNU_SOURCE -#include -#include -#include -#include - -static char * chrootdir = NULL; - -int chroot(const char *path) { - printf("WARNING: CHROOTing to %s was ignored!\n", path); - free(chrootdir); - chrootdir = strdup(path); - return 0; -} -int execvp(const char *file, char *const argv[]) { - static int (*func_execvp) (const char *, char * const []) = NULL; - if (func_execvp == NULL) - func_execvp = (int (*) (const char *, char * const [])) dlsym(RTLD_NEXT, "execvp"); - 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); - return func_execvp(newfile, argv); -} -EOF -testsuccess gcc -fPIC -shared -o noopchroot.so noopchroot.c -ldl - -mkdir -p "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/" -DPKG="${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" -echo "#!/bin/sh -if [ -n \"\$LD_PRELOAD\" ]; then - export LD_PRELOAD=\"${TMPWORKINGDIRECTORY}/noopchroot.so \${LD_PRELOAD}\" -else - export LD_PRELOAD=\"${TMPWORKINGDIRECTORY}/noopchroot.so\" -fi -dpkg \"\$@\"" > $DPKG -chmod +x $DPKG -sed -ie "s|^DPKG::options:: \"dpkg\";\$|DPKG::options:: \"$DPKG\";|" aptconfig.conf - # setup some pre- and post- invokes to check the output isn't garbled later APTHOOK="${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apthook" echo '#!/bin/sh diff --git a/test/integration/test-no-fds-leaked-to-maintainer-scripts b/test/integration/test-no-fds-leaked-to-maintainer-scripts new file mode 100755 index 000000000..6ed120090 --- /dev/null +++ b/test/integration/test-no-fds-leaked-to-maintainer-scripts @@ -0,0 +1,40 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework + +setupenvironment +configarchitecture 'native' +configdpkgnoopchroot + +setupsimplenativepackage "fdleaks" 'native' '1.0' 'unstable' +BUILDDIR="incoming/fdleaks-1.0" +for script in 'preinst' 'postinst' 'prerm' 'postrm'; do + echo '#!/bin/sh +ls -l /proc/self/fd/' > ${BUILDDIR}/debian/$script +done +buildpackage "$BUILDDIR" 'unstable' 'main' 'native' +rm -rf "$BUILDDIR" + +setupaptarchive + +testsuccess aptget install -y fdleaks +msgtest 'Check if fds were not' 'leaked' +if [ "$(grep 'root root' rootdir/tmp/testsuccess.output | wc -l)" = '8' ]; then + msgpass +else + echo + cat rootdir/tmp/testsuccess.output + msgfail +fi + +testsuccess aptget purge -y fdleaks +msgtest 'Check if fds were not' 'leaked' +if [ "$(grep 'root root' rootdir/tmp/testsuccess.output | wc -l)" = '12' ]; then + msgpass +else + echo + cat rootdir/tmp/testsuccess.output + msgfail +fi -- cgit v1.2.3-70-g09d2 From 016bea8214e1826b289025f03890f70a5805db87 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 25 Nov 2014 12:10:15 +0100 Subject: correct architecture detection for 'rc' packages for purge We were already considering these cases, but the code was flawed, so that packages changing architectures are incorrectly handled and hence the wrong architecture is used to call dpkg with, so that dpkg says the package isn't installed (which it isn't for the requested architecture). Closes: 770898 --- apt-pkg/deb/dpkgpm.cc | 16 ++---- test/integration/framework | 24 ++++++--- .../test-ubuntu-bug-761175-remove-purge | 62 ++++++++++++++-------- 3 files changed, 63 insertions(+), 39 deletions(-) (limited to 'test/integration/framework') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 593875071..3fbda0552 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -201,18 +201,10 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg) { pkgCache::VerIterator Ver; for (Ver = Pkg.VersionList(); Ver.end() == false; ++Ver) - { - pkgCache::VerFileIterator Vf = Ver.FileList(); - pkgCache::PkgFileIterator F = Vf.File(); - for (F = Vf.File(); F.end() == false; ++F) - { - if (F && F.Archive()) - { - if (strcmp(F.Archive(), "now")) - return Ver; - } - } - } + for (pkgCache::VerFileIterator Vf = Ver.FileList(); Vf.end() == false; ++Vf) + for (pkgCache::PkgFileIterator F = Vf.File(); F.end() == false; ++F) + if (F->Archive != 0 && strcmp(F.Archive(), "now") == 0) + return Ver; return Ver; } /*}}}*/ diff --git a/test/integration/framework b/test/integration/framework index ff059f59e..298f4c9b2 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -635,12 +635,8 @@ buildaptarchive() { createaptftparchiveconfig() { local COMPRESSORS="$(cut -d' ' -f 1 ${TMPWORKINGDIRECTORY}/rootdir/etc/testcase-compressor.conf | tr '\n' ' ')" - COMPRESSORS="${COMPRESSORS%* }" - 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="$(getarchitectures)" - fi + local COMPRESSORS="${COMPRESSORS%* }" + local ARCHS="$(getarchitectures)" echo -n 'Dir { ArchiveDir "' >> ftparchive.conf echo -n $(readlink -f .) >> ftparchive.conf @@ -1489,3 +1485,19 @@ aptautotest_aptget_update() { done } aptautotest_apt_update() { aptautotest_aptget_update "$@"; } + +testaptautotestnodpkgwarning() { + local TESTCALL="$1" + while [ -n "$2" ]; do + if [ "$2" = '-s' ]; then return; fi + shift + done + testfailure grep '^dpkg: warning:.*ignor.*' "${TMPWORKINGDIRECTORY}/rootdir/tmp-before/${TESTCALL}.output" +} + +aptautotest_aptget_install() { testaptautotestnodpkgwarning "$@"; } +aptautotest_aptget_remove() { testaptautotestnodpkgwarning "$@"; } +aptautotest_aptget_purge() { testaptautotestnodpkgwarning "$@"; } +aptautotest_apt_install() { testaptautotestnodpkgwarning "$@"; } +aptautotest_apt_remove() { testaptautotestnodpkgwarning "$@"; } +aptautotest_apt_purge() { testaptautotestnodpkgwarning "$@"; } diff --git a/test/integration/test-ubuntu-bug-761175-remove-purge b/test/integration/test-ubuntu-bug-761175-remove-purge index 14648e9b8..0b5a91246 100755 --- a/test/integration/test-ubuntu-bug-761175-remove-purge +++ b/test/integration/test-ubuntu-bug-761175-remove-purge @@ -4,33 +4,53 @@ set -e TESTDIR=$(readlink -f $(dirname $0)) . $TESTDIR/framework setupenvironment -configarchitecture 'native' - -setupsimplenativepackage 'compiz-core' 'native' '1.0' 'unstable' -BUILDDIR='incoming/compiz-core-1.0' -mkdir -p ${BUILDDIR}/debian/compiz-core/etc -echo 'foo=bar;' > ${BUILDDIR}/compiz.conf -echo 'compiz.conf /etc/compiz.conf' >> ${BUILDDIR}/debian/install -buildpackage "$BUILDDIR" 'unstable' 'main' 'native' -rm -rf "$BUILDDIR" +configarchitecture 'amd64' 'i386' + +buildcompizpkg() { + setupsimplenativepackage "compiz-core-$1" "$2" "$3" "$4" + BUILDDIR="incoming/compiz-core-$1-$3" + mkdir -p ${BUILDDIR}/debian/compiz-core/etc + echo 'foo=bar;' > ${BUILDDIR}/compiz.conf + echo 'compiz.conf /etc/compiz.conf' >> ${BUILDDIR}/debian/install + buildpackage "$BUILDDIR" "$4" 'main' "$2" + rm -rf "$BUILDDIR" +} +buildcompizpkg 'native' 'all' '1.0' 'stable' +buildcompizpkg 'all' 'native' '1.0' 'stable' +buildcompizpkg 'native' 'native' '2.0' 'unstable' +buildcompizpkg 'all' 'all' '2.0' 'unstable' setupaptarchive +runtests() { + testdpkgnotinstalled compiz-core-$1 + testsuccess aptget install compiz-core-$1 -t "${2:-unstable}" + testdpkginstalled compiz-core-$1 -testdpkgnotinstalled compiz-core -testsuccess aptget install compiz-core -testdpkginstalled compiz-core - -testsuccess aptget remove compiz-core -y -testdpkgnotinstalled compiz-core - -msgtest 'Check that conffiles are still around for' 'compiz-core' -dpkg -l compiz-core | grep -q '^rc' && msgpass || msgfail + testsuccess aptget remove compiz-core-$1 -y + testdpkgnotinstalled compiz-core-$1 + testdpkgstatus 'rc' '1' "compiz-core-$1" -testequal 'Reading package lists... + testequal "Reading package lists... Building dependency tree... Reading state information... The following packages will be REMOVED: - compiz-core* + compiz-core-$1* 0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded. -Purg compiz-core' aptget purge compiz-core -s +Purg compiz-core-$1" aptget purge compiz-core-$1 -s + testsuccess aptget purge compiz-core-$1 -y + testequal "dpkg-query: no packages found matching compiz-core-$1" dpkg -l compiz-core-$1 +} + +msgmsg 'Test in multi arch environment' +runtests 'native' +runtests 'all' +runtests 'native' 'stable' +runtests 'all' 'stable' + +msgmsg 'Test in single arch environment' +configarchitecture 'amd64' +runtests 'native' +runtests 'all' +runtests 'native' 'stable' +runtests 'all' 'stable' -- cgit v1.2.3-70-g09d2 From ecb777ddb4d13bb7a18bbf2ebb8e2c810dcaeb72 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 18 Nov 2014 19:53:56 +0100 Subject: always run 'dpkg --configure -a' at the end of our dpkg callings dpkg checks now for dependencies before running triggers, so that packages can now end up in trigger states (especially those we are not touching at all with our calls) after apt is done running. The solution to this is trivial: Just tell dpkg to configure everything after we have (supposely) configured everything already. In the worst case this means dpkg will have to run a bunch of triggers, usually it will just do nothing though. The code to make this happen was already available, so we just flip a config option here to cause it to be run. This way we can keep pretending that triggers are an implementation detail of dpkg. --triggers-only would supposely work as well, but --configure is more robust in regards to future changes to dpkg and something we will hopefully make use of in future versions anyway (as it was planed at the time this and related options were implemented). Closes: 769609 --- apt-pkg/deb/dpkgpm.cc | 9 ++- test/integration/framework | 25 ++++--- test/integration/test-apt-progress-fd | 67 ++++++++++--------- test/integration/test-apt-progress-fd-deb822 | 18 +++-- test/integration/test-apt-progress-fd-error | 2 +- ...est-bug-769609-triggers-still-pending-after-run | 78 ++++++++++++++++++++++ .../test-no-fds-leaked-to-maintainer-scripts | 6 +- 7 files changed, 149 insertions(+), 56 deletions(-) create mode 100755 test/integration/test-bug-769609-triggers-still-pending-after-run (limited to 'test/integration/framework') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 3fbda0552..79120f6f5 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1039,6 +1039,12 @@ void pkgDPkgPM::BuildPackagesProgressMap() PackagesTotal++; } } + /* one extra: We don't want the progress bar to reach 100%, especially not + if we call dpkg --configure --pending and process a bunch of triggers + while showing 100%. Also, spindown takes a while, so never reaching 100% + is way more correct than reaching 100% while still doing stuff even if + doing it this way is slightly bending the rules */ + ++PackagesTotal; } /*}}}*/ bool pkgDPkgPM::Go(int StatusFd) @@ -1266,9 +1272,8 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) // support subpressing of triggers processing for special // cases like d-i that runs the triggers handling manually - bool const SmartConf = (_config->Find("PackageManager::Configure", "all") != "all"); bool const TriggersPending = _config->FindB("DPkg::TriggersPending", false); - if (_config->FindB("DPkg::ConfigurePending", SmartConf) == true) + if (_config->FindB("DPkg::ConfigurePending", true) == true) List.push_back(Item(Item::ConfigurePending, PkgIterator())); // for the progress diff --git a/test/integration/framework b/test/integration/framework index 298f4c9b2..930ab9367 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1237,10 +1237,13 @@ testnopackage() { fi } -testdpkginstalled() { - msgtest "Test for correctly installed package(s) with" "dpkg -l $*" - local PKGS="$(dpkg -l "$@" 2>/dev/null | grep '^i' | wc -l)" - if [ "$PKGS" != $# ]; then +testdpkgstatus() { + local STATE="$1" + local NR="$2" + shift 2 + msgtest "Test that $NR package(s) are in state $STATE with" "dpkg -l $*" + local PKGS="$(dpkg -l "$@" 2>/dev/null | grep "^${STATE}" | wc -l)" + if [ "$PKGS" != $NR ]; then echo >&2 $PKGS dpkg -l "$@" | grep '^[a-z]' >&2 msgfail @@ -1249,16 +1252,12 @@ testdpkginstalled() { fi } +testdpkginstalled() { + testdpkgstatus 'ii' "$#" "$@" +} + testdpkgnotinstalled() { - msgtest "Test for correctly not-installed package(s) with" "dpkg -l $*" - local PKGS="$(dpkg -l "$@" 2> /dev/null | grep '^i' | wc -l)" - if [ "$PKGS" != 0 ]; then - echo - dpkg -l "$@" | grep '^[a-z]' >&2 - msgfail - else - msgpass - fi + testdpkgstatus 'ii' '0' "$@" } testmarkedauto() { diff --git a/test/integration/test-apt-progress-fd b/test/integration/test-apt-progress-fd index af022f582..90e6ef7e4 100755 --- a/test/integration/test-apt-progress-fd +++ b/test/integration/test-apt-progress-fd @@ -19,13 +19,14 @@ testequal "dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:20:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Installing testing (amd64) -pmstatus:testing:20:Preparing testing (amd64) -pmstatus:testing:40:Unpacking testing (amd64) -pmstatus:testing:60:Preparing to configure testing (amd64) -pmstatus:dpkg-exec:60:Running dpkg -pmstatus:testing:60:Configuring testing (amd64) -pmstatus:testing:80:Configuring testing (amd64) -pmstatus:testing:100:Installed testing (amd64)" cat apt-progress.log +pmstatus:testing:16.6667:Preparing testing (amd64) +pmstatus:testing:33.3333:Unpacking testing (amd64) +pmstatus:testing:50:Preparing to configure testing (amd64) +pmstatus:dpkg-exec:50:Running dpkg +pmstatus:testing:50:Configuring testing (amd64) +pmstatus:testing:66.6667:Configuring testing (amd64) +pmstatus:testing:83.3333:Installed testing (amd64) +pmstatus:dpkg-exec:83.3333:Running dpkg" cat apt-progress.log # upgrade exec 3> apt-progress.log @@ -34,13 +35,14 @@ testequal "dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:20:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Installing testing (amd64) -pmstatus:testing:20:Preparing testing (amd64) -pmstatus:testing:40:Unpacking testing (amd64) -pmstatus:testing:60:Preparing to configure testing (amd64) -pmstatus:dpkg-exec:60:Running dpkg -pmstatus:testing:60:Configuring testing (amd64) -pmstatus:testing:80:Configuring testing (amd64) -pmstatus:testing:100:Installed testing (amd64)" cat apt-progress.log +pmstatus:testing:16.6667:Preparing testing (amd64) +pmstatus:testing:33.3333:Unpacking testing (amd64) +pmstatus:testing:50:Preparing to configure testing (amd64) +pmstatus:dpkg-exec:50:Running dpkg +pmstatus:testing:50:Configuring testing (amd64) +pmstatus:testing:66.6667:Configuring testing (amd64) +pmstatus:testing:83.3333:Installed testing (amd64) +pmstatus:dpkg-exec:83.3333:Running dpkg" cat apt-progress.log # reinstall exec 3> apt-progress.log @@ -49,22 +51,24 @@ testequal "dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:20:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Installing testing (amd64) -pmstatus:testing:20:Preparing testing (amd64) -pmstatus:testing:40:Unpacking testing (amd64) -pmstatus:testing:60:Preparing to configure testing (amd64) -pmstatus:dpkg-exec:60:Running dpkg -pmstatus:testing:60:Configuring testing (amd64) -pmstatus:testing:80:Configuring testing (amd64) -pmstatus:testing:100:Installed testing (amd64)" cat apt-progress.log +pmstatus:testing:16.6667:Preparing testing (amd64) +pmstatus:testing:33.3333:Unpacking testing (amd64) +pmstatus:testing:50:Preparing to configure testing (amd64) +pmstatus:dpkg-exec:50:Running dpkg +pmstatus:testing:50:Configuring testing (amd64) +pmstatus:testing:66.6667:Configuring testing (amd64) +pmstatus:testing:83.3333:Installed testing (amd64) +pmstatus:dpkg-exec:83.3333:Running dpkg" cat apt-progress.log # and remove exec 3> apt-progress.log testsuccess aptget remove testing -y -o APT::Status-Fd=3 testequal "pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Removing testing (amd64) -pmstatus:testing:33.3333:Preparing for removal of testing (amd64) -pmstatus:testing:66.6667:Removing testing (amd64) -pmstatus:testing:100:Removed testing (amd64)" cat apt-progress.log +pmstatus:testing:25:Preparing for removal of testing (amd64) +pmstatus:testing:50:Removing testing (amd64) +pmstatus:testing:75:Removed testing (amd64) +pmstatus:dpkg-exec:75:Running dpkg" cat apt-progress.log # install non-native and ensure we get proper progress info exec 3> apt-progress.log @@ -75,12 +79,13 @@ testequal "dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:20:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing2:0:Installing testing2 (i386) -pmstatus:testing2:20:Preparing testing2 (i386) -pmstatus:testing2:40:Unpacking testing2 (i386) -pmstatus:testing2:60:Preparing to configure testing2 (i386) -pmstatus:dpkg-exec:60:Running dpkg -pmstatus:testing2:60:Configuring testing2 (i386) -pmstatus:testing2:80:Configuring testing2 (i386) -pmstatus:testing2:100:Installed testing2 (i386)" cat apt-progress.log +pmstatus:testing2:16.6667:Preparing testing2 (i386) +pmstatus:testing2:33.3333:Unpacking testing2 (i386) +pmstatus:testing2:50:Preparing to configure testing2 (i386) +pmstatus:dpkg-exec:50:Running dpkg +pmstatus:testing2:50:Configuring testing2 (i386) +pmstatus:testing2:66.6667:Configuring testing2 (i386) +pmstatus:testing2:83.3333:Installed testing2 (i386) +pmstatus:dpkg-exec:83.3333:Running dpkg" cat apt-progress.log rm -f apt-progress*.log diff --git a/test/integration/test-apt-progress-fd-deb822 b/test/integration/test-apt-progress-fd-deb822 index 9d227942d..badc985e4 100755 --- a/test/integration/test-apt-progress-fd-deb822 +++ b/test/integration/test-apt-progress-fd-deb822 @@ -27,37 +27,41 @@ Message: Installing testing (amd64) Status: progress Package: testing:amd64 -Percent: 20 +Percent: 16.6667 Message: Preparing testing (amd64) Status: progress Package: testing:amd64 -Percent: 40 +Percent: 33.3333 Message: Unpacking testing (amd64) Status: progress Package: testing:amd64 -Percent: 60 +Percent: 50 Message: Preparing to configure testing (amd64) Status: progress -Percent: 60 +Percent: 50 Message: Running dpkg Status: progress Package: testing:amd64 -Percent: 60 +Percent: 50 Message: Configuring testing (amd64) Status: progress Package: testing:amd64 -Percent: 80 +Percent: 66.6667 Message: Configuring testing (amd64) Status: progress Package: testing:amd64 -Percent: 100 +Percent: 83.3333 Message: Installed testing (amd64) + +Status: progress +Percent: 83.3333 +Message: Running dpkg " cat apt-progress.log diff --git a/test/integration/test-apt-progress-fd-error b/test/integration/test-apt-progress-fd-error index a47095b9b..632300765 100755 --- a/test/integration/test-apt-progress-fd-error +++ b/test/integration/test-apt-progress-fd-error @@ -18,7 +18,7 @@ setupaptarchive exec 3> apt-progress.log testfailure aptget install foo1 foo2 -y -o APT::Status-Fd=3 msgtest "Ensure correct error message" -if grep -q "aptarchive/pool/foo2_0.8.15_amd64.deb:40:trying to overwrite '/usr/bin/file-conflict', which is also in package foo1 0.8.15" apt-progress.log; then +if grep -q "aptarchive/pool/foo2_0.8.15_amd64.deb:36.3636:trying to overwrite '/usr/bin/file-conflict', which is also in package foo1 0.8.15" apt-progress.log; then msgpass else cat apt-progress.log diff --git a/test/integration/test-bug-769609-triggers-still-pending-after-run b/test/integration/test-bug-769609-triggers-still-pending-after-run new file mode 100755 index 000000000..0588b793f --- /dev/null +++ b/test/integration/test-bug-769609-triggers-still-pending-after-run @@ -0,0 +1,78 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework + +setupenvironment +configarchitecture 'amd64' + +msgtest 'Check if installed dpkg supports' 'noawait trigger' +if dpkg-checkbuilddeps -d 'dpkg (>= 1.16.1)' /dev/null; then + msgpass +else + msgskip 'dpkg version too old' + exit 0 +fi +configdpkgnoopchroot + +buildtriggerpackages() { + local TYPE="$1" + setupsimplenativepackage "triggerable-$TYPE" 'all' '1.0' 'unstable' "Depends: trigdepends-$TYPE" + BUILDDIR="incoming/triggerable-${TYPE}-1.0" + cat >${BUILDDIR}/debian/postinst < ${BUILDDIR}/debian/triggers + buildpackage "$BUILDDIR" 'unstable' 'main' 'native' + rm -rf "$BUILDDIR" + buildsimplenativepackage "trigdepends-$TYPE" 'all' '1.0' 'unstable' +} + +# FIXME: implement test with activate-style triggers +#buildtriggerpackages 'interest' +buildtriggerpackages 'interest-noawait' + +buildsimplenativepackage "trigstuff" 'all' '1.0' 'unstable' + + +setupaptarchive + +runtests() { + local TYPE="$1" + msgmsg 'Working with trigger type' "$TYPE" + testsuccess aptget install triggerable-$TYPE -y + cp rootdir/tmp/testsuccess.output terminal.output + testsuccess grep '^REWRITE ' terminal.output + testdpkginstalled triggerable-$TYPE trigdepends-$TYPE + + testsuccess aptget install trigdepends-$TYPE -y --reinstall + cp rootdir/tmp/testsuccess.output terminal.output + testsuccess grep '^REWRITE ' terminal.output + testsuccess grep ' root root ' terminal.output + testdpkginstalled triggerable-$TYPE trigdepends-$TYPE + + testsuccess aptget install trigstuff -y + cp rootdir/tmp/testsuccess.output terminal.output + testsuccess grep '^REWRITE ' terminal.output + testsuccess grep ' root root ' terminal.output + testdpkginstalled triggerable-$TYPE trigdepends-$TYPE trigstuff + + testsuccess aptget purge trigstuff -y + cp rootdir/tmp/testsuccess.output terminal.output + testsuccess grep '^REWRITE ' terminal.output + testsuccess grep ' root root ' terminal.output + testdpkginstalled triggerable-$TYPE trigdepends-$TYPE + testdpkgnotinstalled trigstuff + + testsuccess aptget purge trigdepends-$TYPE -y + cp rootdir/tmp/testsuccess.output terminal.output + testfailure grep '^REWRITE ' terminal.output + testfailure grep ' root root ' terminal.output + testdpkgnotinstalled triggerable-$TYPE trigdepends-$TYPE +} +#runtests 'interest' +runtests 'interest-noawait' diff --git a/test/integration/test-no-fds-leaked-to-maintainer-scripts b/test/integration/test-no-fds-leaked-to-maintainer-scripts index 428db46ef..cde987bd6 100755 --- a/test/integration/test-no-fds-leaked-to-maintainer-scripts +++ b/test/integration/test-no-fds-leaked-to-maintainer-scripts @@ -48,7 +48,8 @@ startup packages configure configure $PKGNAME 1.0 status unpacked $PKGNAME 1.0 status half-configured $PKGNAME 1.0 -status installed $PKGNAME 1.0" cut -f 3- -d' ' rootdir/var/log/dpkg.log +status installed $PKGNAME 1.0 +startup packages configure" cut -f 3- -d' ' rootdir/var/log/dpkg.log rm -f rootdir/var/log/dpkg.log rootdir/var/log/apt/term.log testsuccess aptget purge -y fdleaks -qq @@ -76,4 +77,5 @@ status config-files $PKGNAME 1.0 status config-files $PKGNAME 1.0 status config-files $PKGNAME 1.0 status config-files $PKGNAME 1.0 -status not-installed $PKGNAME " cut -f 3- -d' ' rootdir/var/log/dpkg.log +status not-installed $PKGNAME +startup packages configure" cut -f 3- -d' ' rootdir/var/log/dpkg.log -- cgit v1.2.3-70-g09d2 From ed793a19ec00b83254029509bc516e3ba911c75a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 29 Nov 2014 17:59:52 +0100 Subject: dispose http(s) 416 error page as non-content MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Real webservers (like apache) actually send an error page with a 416 response, but our client didn't expect it leaving the page on the socket to be parsed as response for the next request (http) or as file content (https), which isn't what we want at all… Symptom is a "Bad header line" as html usually doesn't parse that well to an http-header. This manifests itself e.g. if we have a complete file (or larger) in partial/ which isn't discarded by If-Range as the server doesn't support it (or it is just newer, think: mirror rotation). It is a sort-of regression of 78c72d0ce22e00b194251445aae306df357d5c1a, which removed the filesize - 1 trick, but this had its own problems… To properly test this our webserver gains the ability to reply with transfer-encoding: chunked as most real webservers will use it to send the dynamically generated error pages. Closes: 768797 --- cmdline/apt-helper.cc | 31 +++-- methods/http.cc | 2 + methods/https.cc | 15 ++- methods/server.cc | 26 ++-- methods/server.h | 5 +- test/integration/framework | 4 +- test/integration/test-partial-file-support | 62 ++++++++- test/interactive-helper/aptwebserver.cc | 193 ++++++++++++++++++----------- 8 files changed, 233 insertions(+), 105 deletions(-) (limited to 'test/integration/framework') diff --git a/cmdline/apt-helper.cc b/cmdline/apt-helper.cc index 1b832f165..a05ae90a2 100644 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@ -51,22 +51,33 @@ static bool DoDownloadFile(CommandLine &CmdL) AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); pkgAcquire Fetcher(&Stat); - std::string download_uri = CmdL.FileList[1]; - std::string targetfile = CmdL.FileList[2]; - std::string hash; - if (CmdL.FileSize() > 3) - hash = CmdL.FileList[3]; - // we use download_uri as descr and targetfile as short-descr - new pkgAcqFile(&Fetcher, download_uri, hash, 0, download_uri, targetfile, - "dest-dir-ignored", targetfile); + size_t fileind = 0; + std::vector targetfiles; + while (fileind + 2 <= CmdL.FileSize()) + { + std::string download_uri = CmdL.FileList[fileind + 1]; + std::string targetfile = CmdL.FileList[fileind + 2]; + std::string hash; + if (CmdL.FileSize() > fileind + 3) + hash = CmdL.FileList[fileind + 3]; + // we use download_uri as descr and targetfile as short-descr + new pkgAcqFile(&Fetcher, download_uri, hash, 0, download_uri, targetfile, + "dest-dir-ignored", targetfile); + targetfiles.push_back(targetfile); + fileind += 3; + } // Disable drop-privs if "_apt" can not write to the target dir CheckDropPrivsMustBeDisabled(Fetcher); bool Failed = false; - if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true || - FileExists(targetfile) == false) + if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true) return _error->Error(_("Download Failed")); + if (targetfiles.empty() == false) + for (std::vector::const_iterator f = targetfiles.begin(); f != targetfiles.end(); ++f) + if (FileExists(*f) == false) + return _error->Error(_("Download Failed")); + return true; } diff --git a/methods/http.cc b/methods/http.cc index a5de13511..ad1347d36 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -444,6 +444,8 @@ bool HttpServerState::RunData(FileFd * const File) loss of the connection means we are done */ if (Encoding == Closes) In.Limit(-1); + else if (JunkSize != 0) + In.Limit(JunkSize); else In.Limit(Size - StartPos); diff --git a/methods/https.cc b/methods/https.cc index 366148e19..23b3a10d4 100644 --- a/methods/https.cc +++ b/methods/https.cc @@ -69,6 +69,9 @@ HttpsMethod::parse_header(void *buffer, size_t size, size_t nmemb, void *userp) { me->Server->Result = 200; me->Server->StartPos = me->Server->Size; + // the actual size is not important for https as curl will deal with it + // by itself and e.g. doesn't bother us with transport-encoding… + me->Server->JunkSize = std::numeric_limits::max(); } else me->Server->StartPos = 0; @@ -86,19 +89,25 @@ size_t HttpsMethod::write_data(void *buffer, size_t size, size_t nmemb, void *userp) { HttpsMethod *me = (HttpsMethod *)userp; + size_t buffer_size = size * nmemb; + // we don't need to count the junk here, just drop anything we get as + // we don't always know how long it would be, e.g. in chunked encoding. + if (me->Server->JunkSize != 0) + return buffer_size; if (me->Res.Size == 0) me->URIStart(me->Res); - if(me->File->Write(buffer, size*nmemb) != true) + if(me->File->Write(buffer, buffer_size) != true) return false; if(me->Queue->MaximumSize > 0 && me->File->Tell() > me->Queue->MaximumSize) { me->SetFailReason("MaximumSizeExceeded"); - return _error->Error("Writing more data than expected (%llu > %llu)", + _error->Error("Writing more data than expected (%llu > %llu)", me->TotalWritten, me->Queue->MaximumSize); + return 0; } - return size*nmemb; + return buffer_size; } int diff --git a/methods/server.cc b/methods/server.cc index c4689ff12..9b3d39cf2 100644 --- a/methods/server.cc +++ b/methods/server.cc @@ -55,6 +55,7 @@ ServerState::RunHeadersResult ServerState::RunHeaders(FileFd * const File, Minor = 0; Result = 0; Size = 0; + JunkSize = 0; StartPos = 0; Encoding = Closes; HaveContent = false; @@ -163,14 +164,14 @@ bool ServerState::HeaderLine(string Line) Encoding = Stream; HaveContent = true; - // The length is already set from the Content-Range header - if (StartPos != 0) - return true; + unsigned long long * SizePtr = &Size; + if (Result == 416) + SizePtr = &JunkSize; - Size = strtoull(Val.c_str(), NULL, 10); - if (Size >= std::numeric_limits::max()) + *SizePtr = strtoull(Val.c_str(), NULL, 10); + if (*SizePtr >= std::numeric_limits::max()) return _error->Errno("HeaderLine", _("The HTTP server sent an invalid Content-Length header")); - else if (Size == 0) + else if (*SizePtr == 0) HaveContent = false; return true; } @@ -187,10 +188,7 @@ bool ServerState::HeaderLine(string Line) // §14.16 says 'byte-range-resp-spec' should be a '*' in case of 416 if (Result == 416 && sscanf(Val.c_str(), "bytes */%llu",&Size) == 1) - { - StartPos = 1; // ignore Content-Length, it would override Size - HaveContent = false; - } + ; // we got the expected filesize which is all we wanted else if (sscanf(Val.c_str(),"bytes %llu-%*u/%llu",&StartPos,&Size) != 2) return _error->Error(_("The HTTP server sent an invalid Content-Range header")); if ((unsigned long long)StartPos > Size) @@ -308,9 +306,15 @@ ServerMethod::DealWithHeaders(FetchResult &Res) if ((unsigned long long)SBuf.st_size == Server->Size) { // the file is completely downloaded, but was not moved + if (Server->HaveContent == true) + { + // Send to error page to dev/null + FileFd DevNull("/dev/null",FileFd::WriteExists); + Server->RunData(&DevNull); + } + Server->HaveContent = false; Server->StartPos = Server->Size; Server->Result = 200; - Server->HaveContent = false; } else if (unlink(Queue->DestFile.c_str()) == 0) { diff --git a/methods/server.h b/methods/server.h index 7d5198478..b974ec89a 100644 --- a/methods/server.h +++ b/methods/server.h @@ -34,7 +34,8 @@ struct ServerState char Code[360]; // These are some statistics from the last parsed header lines - unsigned long long Size; + unsigned long long Size; // size of the usable content (aka: the file) + unsigned long long JunkSize; // size of junk content (aka: server error pages) unsigned long long StartPos; time_t Date; bool HaveContent; @@ -73,7 +74,7 @@ struct ServerState RunHeadersResult RunHeaders(FileFd * const File, const std::string &Uri); bool Comp(URI Other) const {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;}; - virtual void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; Size = 0; + virtual void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; Size = 0; JunkSize = 0; StartPos = 0; Encoding = Closes; time(&Date); HaveContent = false; State = Header; Persistent = false; Pipeline = true; MaximumSize = 0;}; virtual bool WriteResponse(std::string const &Data) = 0; diff --git a/test/integration/framework b/test/integration/framework index 930ab9367..f7f69f5d5 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1119,8 +1119,8 @@ acquire::cdrom::autodetect 0;" > rootdir/etc/apt/apt.conf.d/00cdrom } downloadfile() { - local PROTO="$(echo "$1" | cut -d':' -f 1 )" - apthelper -o Debug::Acquire::${PROTO}=1 \ + local PROTO="${1%%:*}" + apthelper -o Debug::Acquire::${PROTO}=1 -o Debug::pkgAcquire::Worker=1 \ download-file "$1" "$2" 2>&1 || true # only if the file exists the download was successful if [ -r "$2" ]; then diff --git a/test/integration/test-partial-file-support b/test/integration/test-partial-file-support index 98b2f242a..b6b305d25 100755 --- a/test/integration/test-partial-file-support +++ b/test/integration/test-partial-file-support @@ -24,13 +24,25 @@ testdownloadfile() { else msgpass fi - cat "$DOWNLOADLOG" | while read field hash; do + sed -e '/^ <- / s#%20# #g' -e '/^ <- / s#%0a#\n#g' "$DOWNLOADLOG" | grep '^.*-Hash: ' > receivedhashes.log + testsuccess test -s receivedhashes.log + local HASHES_OK=0 + local HASHES_BAD=0 + while read field hash; do local EXPECTED case "$field" in 'MD5Sum-Hash:') EXPECTED="$(md5sum "$TESTFILE" | cut -d' ' -f 1)";; 'SHA1-Hash:') EXPECTED="$(sha1sum "$TESTFILE" | cut -d' ' -f 1)";; 'SHA256-Hash:') EXPECTED="$(sha256sum "$TESTFILE" | cut -d' ' -f 1)";; 'SHA512-Hash:') EXPECTED="$(sha512sum "$TESTFILE" | cut -d' ' -f 1)";; + 'Checksum-FileSize-Hash:') + #filesize is too weak to check for != + if [ "$4" = '=' ]; then + EXPECTED="$(stat -c '%s' "$TESTFILE")" + else + continue + fi + ;; *) continue;; esac if [ "$4" = '=' ]; then @@ -40,15 +52,41 @@ testdownloadfile() { fi if [ "$EXPECTED" "$4" "$hash" ]; then msgpass + HASHES_OK=$((HASHES_OK+1)); else - cat >&2 "$DOWNLOADLOG" msgfail "expected: $EXPECTED ; got: $hash" + HASHES_BAD=$((HASHES_BAD+1)); fi - done + done < receivedhashes.log + msgtest 'At least one good hash and no bad ones' + if [ $HASHES_OK -eq 0 ] || [ $HASHES_BAD -ne 0 ]; then + cat >&2 "$DOWNLOADLOG" + msgfail + else + msgpass + fi } TESTFILE='aptarchive/testfile' cp -a ${TESTDIR}/framework $TESTFILE +cp -a ${TESTDIR}/framework "${TESTFILE}2" + +followuprequest() { + local DOWN='./downloaded/testfile' + + copysource $TESTFILE 1M $DOWN + testdownloadfile 'completely downloaded file' "${1}/testfile" "$DOWN" '=' + testwebserverlaststatuscode '416' "$DOWNLOADLOG" + + copysource $TESTFILE 1M $DOWN + copysource "${TESTFILE}2" 20 "${DOWN}2" + msgtest 'Testing download of files with' 'completely downloaded file + partial file' + testsuccess --nomsg apthelper -o Debug::Acquire::${1%%:*}=1 -o Debug::pkgAcquire::Worker=1 \ + download-file "$1/testfile" "$DOWN" '' "$1/testfile2" "${DOWN}2" + testwebserverlaststatuscode '206' 'rootdir/tmp/testsuccess.output' + testsuccess diff -u "$TESTFILE" "${DOWN}" + testsuccess diff -u "${DOWN}" "${DOWN}2" +} testrun() { webserverconfig 'aptwebserver::support::range' 'true' @@ -66,9 +104,11 @@ testrun() { testdownloadfile 'invalid partial data' "${1}/testfile" "$DOWN" '!=' testwebserverlaststatuscode '206' "$DOWNLOADLOG" - copysource $TESTFILE 1M $DOWN - testdownloadfile 'completely downloaded file' "${1}/testfile" "$DOWN" '=' - testwebserverlaststatuscode '416' "$DOWNLOADLOG" + webserverconfig 'aptwebserver::closeOnError' 'false' + followuprequest "$1" + webserverconfig 'aptwebserver::closeOnError' 'true' + followuprequest "$1" + webserverconfig 'aptwebserver::closeOnError' 'false' copysource /dev/zero 1M $DOWN testdownloadfile 'too-big partial file' "${1}/testfile" "$DOWN" '=' @@ -86,8 +126,18 @@ testrun() { testwebserverlaststatuscode '200' "$DOWNLOADLOG" } +msgmsg 'http: Test with Content-Length' +webserverconfig 'aptwebserver::chunked-transfer-encoding' 'false' +testrun 'http://localhost:8080' +msgmsg 'http: Test with Transfer-Encoding: chunked' +webserverconfig 'aptwebserver::chunked-transfer-encoding' 'true' testrun 'http://localhost:8080' changetohttpswebserver +msgmsg 'https: Test with Content-Length' +webserverconfig 'aptwebserver::chunked-transfer-encoding' 'false' +testrun 'https://localhost:4433' +msgmsg 'https: Test with Transfer-Encoding: chunked' +webserverconfig 'aptwebserver::chunked-transfer-encoding' 'true' testrun 'https://localhost:4433' diff --git a/test/interactive-helper/aptwebserver.cc b/test/interactive-helper/aptwebserver.cc index 00004a524..ca6f88c58 100644 --- a/test/interactive-helper/aptwebserver.cc +++ b/test/interactive-helper/aptwebserver.cc @@ -19,6 +19,8 @@ #include #include #include + +#include #include #include #include @@ -79,12 +81,21 @@ static char const * httpcodeToStr(int const httpcode) /*{{{*/ return NULL; } /*}}}*/ +static bool chunkedTransferEncoding(std::list const &headers) { + if (std::find(headers.begin(), headers.end(), "Transfer-Encoding: chunked") != headers.end()) + return true; + if (_config->FindB("aptwebserver::chunked-transfer-encoding", false) == true) + return true; + return false; +} static void addFileHeaders(std::list &headers, FileFd &data)/*{{{*/ { - std::ostringstream contentlength; - contentlength << "Content-Length: " << data.FileSize(); - headers.push_back(contentlength.str()); - + if (chunkedTransferEncoding(headers) == false) + { + std::ostringstream contentlength; + contentlength << "Content-Length: " << data.FileSize(); + headers.push_back(contentlength.str()); + } std::string lastmodified("Last-Modified: "); lastmodified.append(TimeRFC1123(data.ModificationTime())); headers.push_back(lastmodified); @@ -92,9 +103,12 @@ static void addFileHeaders(std::list &headers, FileFd &data)/*{{{*/ /*}}}*/ static void addDataHeaders(std::list &headers, std::string &data)/*{{{*/ { - std::ostringstream contentlength; - contentlength << "Content-Length: " << data.size(); - headers.push_back(contentlength.str()); + if (chunkedTransferEncoding(headers) == false) + { + std::ostringstream contentlength; + contentlength << "Content-Length: " << data.size(); + headers.push_back(contentlength.str()); + } } /*}}}*/ static bool sendHead(int const client, int const httpcode, std::list &headers)/*{{{*/ @@ -114,6 +128,9 @@ static bool sendHead(int const client, int const httpcode, std::list>> RESPONSE to " << client << " >>>" << std::endl; bool Success = true; for (std::list::const_iterator h = headers.begin(); @@ -130,25 +147,55 @@ static bool sendHead(int const client, int const httpcode, std::list const &headers, FileFd &data)/*{{{*/ { bool Success = true; + bool const chunked = chunkedTransferEncoding(headers); char buffer[500]; unsigned long long actual = 0; while ((Success &= data.Read(buffer, sizeof(buffer), &actual)) == true) { if (actual == 0) break; - Success &= FileFd::Write(client, buffer, actual); + + if (chunked == true) + { + std::string size; + strprintf(size, "%llX\r\n", actual); + Success &= FileFd::Write(client, size.c_str(), size.size()); + Success &= FileFd::Write(client, buffer, actual); + Success &= FileFd::Write(client, "\r\n", strlen("\r\n")); + } + else + Success &= FileFd::Write(client, buffer, actual); + } + if (chunked == true) + { + char const * const finish = "0\r\n\r\n"; + Success &= FileFd::Write(client, finish, strlen(finish)); } if (Success == false) - std::cerr << "SENDFILE: READ/WRITE ERROR to " << client << std::endl; + std::cerr << "SENDFILE:" << (chunked ? " CHUNKED" : "") << " READ/WRITE ERROR to " << client << std::endl; return Success; } /*}}}*/ -static bool sendData(int const client, std::string const &data) /*{{{*/ +static bool sendData(int const client, std::list const &headers, std::string const &data)/*{{{*/ { - if (FileFd::Write(client, data.c_str(), data.size()) == false) + if (chunkedTransferEncoding(headers) == true) + { + unsigned long long const ullsize = data.length(); + std::string size; + strprintf(size, "%llX\r\n", ullsize); + char const * const finish = "\r\n0\r\n\r\n"; + if (FileFd::Write(client, size.c_str(), size.length()) == false || + FileFd::Write(client, data.c_str(), ullsize) == false || + FileFd::Write(client, finish, strlen(finish)) == false) + { + std::cerr << "SENDDATA: CHUNK WRITE ERROR to " << client << std::endl; + return false; + } + } + else if (FileFd::Write(client, data.c_str(), data.size()) == false) { std::cerr << "SENDDATA: WRITE ERROR to " << client << std::endl; return false; @@ -157,33 +204,38 @@ static bool sendData(int const client, std::string const &data) /*{{{*/ } /*}}}*/ static void sendError(int const client, int const httpcode, std::string const &request,/*{{{*/ - bool content, std::string const &error = "", std::list headers = std::list()) + bool const content, std::string const &error, std::list &headers) { std::string response(""); response.append(httpcodeToStr(httpcode)).append(""); response.append("

").append(httpcodeToStr(httpcode)).append("

"); if (httpcode != 200) - { - if (error.empty() == false) - response.append("

Error: ").append(error).append("

"); - response.append("This error is a result of the request:
");
-   }
+      response.append("

Error: "); + else + response.append("

Success: "); + if (error.empty() == false) + response.append(error); + else + response.append(httpcodeToStr(httpcode)); + if (httpcode != 200) + response.append("

This error is a result of the request:
");
    else
-   {
-      if (error.empty() == false)
-	 response.append("

Success: ").append(error).append("

"); response.append("The successfully executed operation was requested by:
");
-   }
    response.append(request).append("
"); + if (httpcode != 200) + { + if (_config->FindB("aptwebserver::closeOnError", false) == true) + headers.push_back("Connection: close"); + } addDataHeaders(headers, response); sendHead(client, httpcode, headers); if (content == true) - sendData(client, response); + sendData(client, headers, response); } static void sendSuccess(int const client, std::string const &request, - bool content, std::string const &error = "") + bool const content, std::string const &error, std::list &headers) { - sendError(client, 200, request, content, error); + sendError(client, 200, request, content, error, headers); } /*}}}*/ static void sendRedirect(int const client, int const httpcode, std::string const &uri,/*{{{*/ @@ -220,7 +272,7 @@ static void sendRedirect(int const client, int const httpcode, std::string const headers.push_back(location); sendHead(client, httpcode, headers); if (content == true) - sendData(client, response); + sendData(client, headers, response); } /*}}}*/ static int filter_hidden_files(const struct dirent *a) /*{{{*/ @@ -262,16 +314,15 @@ static int grouped_alpha_case_sort(const struct dirent **a, const struct dirent } /*}}}*/ static void sendDirectoryListing(int const client, std::string const &dir,/*{{{*/ - std::string const &request, bool content) + std::string const &request, bool content, std::list &headers) { - std::list headers; std::ostringstream listing; struct dirent **namelist; int const counter = scandir(dir.c_str(), &namelist, filter_hidden_files, grouped_alpha_case_sort); if (counter == -1) { - sendError(client, 500, request, content); + sendError(client, 500, request, content, "scandir failed", headers); return; } @@ -310,18 +361,18 @@ static void sendDirectoryListing(int const client, std::string const &dir,/*{{{* addDataHeaders(headers, response); sendHead(client, 200, headers); if (content == true) - sendData(client, response); + sendData(client, headers, response); } /*}}}*/ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ std::string &filename, std::string ¶ms, bool &sendContent, - bool &closeConnection) + bool &closeConnection, std::list &headers) { if (strncmp(request.c_str(), "HEAD ", 5) == 0) sendContent = false; if (strncmp(request.c_str(), "GET ", 4) != 0) { - sendError(client, 501, request, true); + sendError(client, 501, request, true, "", headers); return false; } @@ -332,7 +383,7 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ if (lineend == std::string::npos || filestart == std::string::npos || fileend == std::string::npos || filestart == fileend) { - sendError(client, 500, request, sendContent, "Filename can't be extracted"); + sendError(client, 500, request, sendContent, "Filename can't be extracted", headers); return false; } @@ -344,14 +395,14 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ closeConnection = strcasecmp(LookupTag(request, "Connection", "Keep-Alive").c_str(), "close") == 0; else { - sendError(client, 500, request, sendContent, "Not a HTTP/1.{0,1} request"); + sendError(client, 500, request, sendContent, "Not a HTTP/1.{0,1} request", headers); return false; } filename = request.substr(filestart, fileend - filestart); if (filename.find(' ') != std::string::npos) { - sendError(client, 500, request, sendContent, "Filename contains an unencoded space"); + sendError(client, 500, request, sendContent, "Filename contains an unencoded space", headers); return false; } @@ -359,7 +410,7 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ if (host.empty() == true) { // RFC 2616 §14.23 requires Host - sendError(client, 400, request, sendContent, "Host header is required"); + sendError(client, 400, request, sendContent, "Host header is required", headers); return false; } host = "http://" + host; @@ -370,7 +421,7 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ { if (absolute.find("uri") == std::string::npos) { - sendError(client, 400, request, sendContent, "Request is absoluteURI, but configured to not accept that"); + sendError(client, 400, request, sendContent, "Request is absoluteURI, but configured to not accept that", headers); return false; } @@ -382,9 +433,9 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ if (authConf.empty() != auth.empty()) { if (auth.empty()) - sendError(client, 407, request, sendContent, "Proxy requires authentication"); + sendError(client, 407, request, sendContent, "Proxy requires authentication", headers); else - sendError(client, 407, request, sendContent, "Client wants to authenticate to proxy, but proxy doesn't need it"); + sendError(client, 407, request, sendContent, "Client wants to authenticate to proxy, but proxy doesn't need it", headers); return false; } if (authConf.empty() == false) @@ -395,7 +446,7 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ auth.erase(0, strlen(basic)); if (auth != authConf) { - sendError(client, 407, request, sendContent, "Proxy-Authentication doesn't match"); + sendError(client, 407, request, sendContent, "Proxy-Authentication doesn't match", headers); return false; } } @@ -410,7 +461,7 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ } else if (absolute.find("path") == std::string::npos && APT::String::Startswith(filename, "/_config/") == false) { - sendError(client, 400, request, sendContent, "Request is absolutePath, but configured to not accept that"); + sendError(client, 400, request, sendContent, "Request is absolutePath, but configured to not accept that", headers); return false; } @@ -421,9 +472,9 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ if (authConf.empty() != auth.empty()) { if (auth.empty()) - sendError(client, 401, request, sendContent, "Server requires authentication"); + sendError(client, 401, request, sendContent, "Server requires authentication", headers); else - sendError(client, 401, request, sendContent, "Client wants to authenticate to server, but server doesn't need it"); + sendError(client, 401, request, sendContent, "Client wants to authenticate to server, but server doesn't need it", headers); return false; } if (authConf.empty() == false) @@ -434,13 +485,12 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ auth.erase(0, strlen(basic)); if (auth != authConf) { - sendError(client, 401, request, sendContent, "Authentication doesn't match"); + sendError(client, 401, request, sendContent, "Authentication doesn't match", headers); return false; } } else { - std::list headers; headers.push_back("WWW-Authenticate: Basic"); sendError(client, 401, request, sendContent, "Unsupported Authentication Scheme", headers); return false; @@ -463,7 +513,8 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ filename.find_first_of("\r\n\t\f\v") != std::string::npos || filename.find("/../") != std::string::npos) { - sendError(client, 400, request, sendContent, "Filename contains illegal character (sequence)"); + std::list headers; + sendError(client, 400, request, sendContent, "Filename contains illegal character (sequence)", headers); return false; } @@ -499,7 +550,8 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ return true; } /*}}}*/ -static bool handleOnTheFlyReconfiguration(int const client, std::string const &request, std::vector parts)/*{{{*/ +static bool handleOnTheFlyReconfiguration(int const client, std::string const &request,/*{{{*/ + std::vector parts, std::list &headers) { size_t const pcount = parts.size(); for (size_t i = 0; i < pcount; ++i) @@ -507,40 +559,38 @@ static bool handleOnTheFlyReconfiguration(int const client, std::string const &r if (pcount == 4 && parts[1] == "set") { _config->Set(parts[2], parts[3]); - sendSuccess(client, request, true, "Option '" + parts[2] + "' was set to '" + parts[3] + "'!"); + sendSuccess(client, request, true, "Option '" + parts[2] + "' was set to '" + parts[3] + "'!", headers); return true; } else if (pcount == 4 && parts[1] == "find") { - std::list headers; std::string response = _config->Find(parts[2], parts[3]); addDataHeaders(headers, response); sendHead(client, 200, headers); - sendData(client, response); + sendData(client, headers, response); return true; } else if (pcount == 3 && parts[1] == "find") { - std::list headers; if (_config->Exists(parts[2]) == true) { std::string response = _config->Find(parts[2]); addDataHeaders(headers, response); sendHead(client, 200, headers); - sendData(client, response); + sendData(client, headers, response); return true; } - sendError(client, 404, request, "Requested Configuration option doesn't exist."); + sendError(client, 404, request, true, "Requested Configuration option doesn't exist", headers); return false; } else if (pcount == 3 && parts[1] == "clear") { _config->Clear(parts[2]); - sendSuccess(client, request, true, "Option '" + parts[2] + "' was cleared."); + sendSuccess(client, request, true, "Option '" + parts[2] + "' was cleared.", headers); return true; } - sendError(client, 400, request, true, "Unknown on-the-fly configuration request"); + sendError(client, 400, request, true, "Unknown on-the-fly configuration request", headers); return false; } /*}}}*/ @@ -549,18 +599,22 @@ static void * handleClient(void * voidclient) /*{{{*/ int client = *((int*)(voidclient)); std::clog << "ACCEPT client " << client << std::endl; std::vector messages; - while (ReadMessages(client, messages)) + bool closeConnection = false; + std::list headers; + while (closeConnection == false && ReadMessages(client, messages)) { - bool closeConnection = false; + // if we announced a closing, do the close + if (std::find(headers.begin(), headers.end(), std::string("Connection: close")) != headers.end()) + break; + headers.clear(); for (std::vector::const_iterator m = messages.begin(); m != messages.end() && closeConnection == false; ++m) { std::clog << ">>> REQUEST from " << client << " >>>" << std::endl << *m << std::endl << "<<<<<<<<<<<<<<<<" << std::endl; - std::list headers; std::string filename; std::string params; bool sendContent = true; - if (parseFirstLine(client, *m, filename, params, sendContent, closeConnection) == false) + if (parseFirstLine(client, *m, filename, params, sendContent, closeConnection, headers) == false) continue; // special webserver command request @@ -569,7 +623,7 @@ static void * handleClient(void * voidclient) /*{{{*/ std::vector parts = VectorizeString(filename, '/'); if (parts[0] == "_config") { - handleOnTheFlyReconfiguration(client, *m, parts); + handleOnTheFlyReconfiguration(client, *m, parts, headers); continue; } } @@ -601,7 +655,7 @@ static void * handleClient(void * voidclient) /*{{{*/ { char error[300]; regerror(res, pattern, error, sizeof(error)); - sendError(client, 500, *m, sendContent, error); + sendError(client, 500, *m, sendContent, error, headers); continue; } if (regexec(pattern, filename.c_str(), 0, 0, 0) == 0) @@ -620,7 +674,7 @@ static void * handleClient(void * voidclient) /*{{{*/ if (_config->FindB("aptwebserver::support::http", true) == false && LookupTag(*m, "Host").find(":4433") == std::string::npos) { - sendError(client, 400, *m, sendContent, "HTTP disabled, all requests must be HTTPS"); + sendError(client, 400, *m, sendContent, "HTTP disabled, all requests must be HTTPS", headers); continue; } else if (RealFileExists(filename) == true) @@ -676,17 +730,16 @@ static void * handleClient(void * voidclient) /*{{{*/ headers.push_back(contentrange.str()); sendHead(client, 206, headers); if (sendContent == true) - sendFile(client, data); + sendFile(client, headers, data); continue; } else { - headers.push_back("Content-Length: 0"); std::ostringstream contentrange; contentrange << "Content-Range: bytes */" << filesize; headers.push_back(contentrange.str()); - sendHead(client, 416, headers); - continue; + sendError(client, 416, *m, sendContent, "", headers); + break; } } } @@ -695,22 +748,20 @@ static void * handleClient(void * voidclient) /*{{{*/ addFileHeaders(headers, data); sendHead(client, 200, headers); if (sendContent == true) - sendFile(client, data); + sendFile(client, headers, data); } else if (DirectoryExists(filename) == true) { if (filename[filename.length()-1] == '/') - sendDirectoryListing(client, filename, *m, sendContent); + sendDirectoryListing(client, filename, *m, sendContent, headers); else sendRedirect(client, 301, filename.append("/"), *m, sendContent); } else - sendError(client, 404, *m, sendContent); + sendError(client, 404, *m, sendContent, "", headers); } _error->DumpErrors(std::cerr); messages.clear(); - if (closeConnection == true) - break; } close(client); std::clog << "CLOSE client " << client << std::endl; -- cgit v1.2.3-70-g09d2 From 92e8c1ff287ab829de825e00cdf94744e699ff97 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 29 Nov 2014 17:59:52 +0100 Subject: dispose http(s) 416 error page as non-content MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Real webservers (like apache) actually send an error page with a 416 response, but our client didn't expect it leaving the page on the socket to be parsed as response for the next request (http) or as file content (https), which isn't what we want at all… Symptom is a "Bad header line" as html usually doesn't parse that well to an http-header. This manifests itself e.g. if we have a complete file (or larger) in partial/ which isn't discarded by If-Range as the server doesn't support it (or it is just newer, think: mirror rotation). It is a sort-of regression of 78c72d0ce22e00b194251445aae306df357d5c1a, which removed the filesize - 1 trick, but this had its own problems… To properly test this our webserver gains the ability to reply with transfer-encoding: chunked as most real webservers will use it to send the dynamically generated error pages. (The tests and their binary helpers had to be slightly modified to apply, but the patch to fix the issue itself is unchanged.) Closes: 768797 --- cmdline/apt-helper.cc | 35 ++++-- methods/http.cc | 2 + methods/https.cc | 12 +- methods/server.cc | 26 +++-- methods/server.h | 5 +- test/integration/framework | 6 +- test/integration/test-apt-helper | 24 ++-- test/integration/test-partial-file-support | 62 +++++++++- test/interactive-helper/aptwebserver.cc | 181 ++++++++++++++++++----------- 9 files changed, 241 insertions(+), 112 deletions(-) (limited to 'test/integration/framework') diff --git a/cmdline/apt-helper.cc b/cmdline/apt-helper.cc index dd43ea1bc..63f70983c 100644 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@ -48,23 +48,34 @@ static bool DoDownloadFile(CommandLine &CmdL) if (CmdL.FileSize() <= 2) return _error->Error(_("Must specify at least one pair url/filename")); - pkgAcquire Fetcher; AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); Fetcher.Setup(&Stat); - std::string download_uri = CmdL.FileList[1]; - std::string targetfile = CmdL.FileList[2]; - std::string hash; - if (CmdL.FileSize() > 3) - hash = CmdL.FileList[3]; - // we use download_uri as descr and targetfile as short-descr - new pkgAcqFile(&Fetcher, download_uri, hash, 0, download_uri, targetfile, - "dest-dir-ignored", targetfile); - Fetcher.Run(); + + size_t fileind = 0; + std::vector targetfiles; + while (fileind + 2 <= CmdL.FileSize()) + { + std::string download_uri = CmdL.FileList[fileind + 1]; + std::string targetfile = CmdL.FileList[fileind + 2]; + std::string hash; + if (CmdL.FileSize() > fileind + 3) + hash = CmdL.FileList[fileind + 3]; + // we use download_uri as descr and targetfile as short-descr + new pkgAcqFile(&Fetcher, download_uri, hash, 0, download_uri, targetfile, + "dest-dir-ignored", targetfile); + targetfiles.push_back(targetfile); + fileind += 3; + } + bool Failed = false; - if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true || - FileExists(targetfile) == false) + if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true) return _error->Error(_("Download Failed")); + if (targetfiles.empty() == false) + for (std::vector::const_iterator f = targetfiles.begin(); f != targetfiles.end(); ++f) + if (FileExists(*f) == false) + return _error->Error(_("Download Failed")); + return true; } diff --git a/methods/http.cc b/methods/http.cc index f2a4a4db6..1b996db98 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -440,6 +440,8 @@ bool HttpServerState::RunData(FileFd * const File) loss of the connection means we are done */ if (Encoding == Closes) In.Limit(-1); + else if (JunkSize != 0) + In.Limit(JunkSize); else In.Limit(Size - StartPos); diff --git a/methods/https.cc b/methods/https.cc index 0499af0c5..65a744e2a 100644 --- a/methods/https.cc +++ b/methods/https.cc @@ -59,6 +59,9 @@ HttpsMethod::parse_header(void *buffer, size_t size, size_t nmemb, void *userp) { me->Server->Result = 200; me->Server->StartPos = me->Server->Size; + // the actual size is not important for https as curl will deal with it + // by itself and e.g. doesn't bother us with transport-encoding… + me->Server->JunkSize = std::numeric_limits::max(); } else me->Server->StartPos = 0; @@ -76,13 +79,18 @@ size_t HttpsMethod::write_data(void *buffer, size_t size, size_t nmemb, void *userp) { HttpsMethod *me = (HttpsMethod *)userp; + size_t buffer_size = size * nmemb; + // we don't need to count the junk here, just drop anything we get as + // we don't always know how long it would be, e.g. in chunked encoding. + if (me->Server->JunkSize != 0) + return buffer_size; if (me->Res.Size == 0) me->URIStart(me->Res); - if(me->File->Write(buffer, size*nmemb) != true) + if(me->File->Write(buffer, buffer_size) != true) return false; - return size*nmemb; + return buffer_size; } int diff --git a/methods/server.cc b/methods/server.cc index 92d94e638..cb0341d5f 100644 --- a/methods/server.cc +++ b/methods/server.cc @@ -55,6 +55,7 @@ ServerState::RunHeadersResult ServerState::RunHeaders(FileFd * const File, Minor = 0; Result = 0; Size = 0; + JunkSize = 0; StartPos = 0; Encoding = Closes; HaveContent = false; @@ -163,14 +164,14 @@ bool ServerState::HeaderLine(string Line) Encoding = Stream; HaveContent = true; - // The length is already set from the Content-Range header - if (StartPos != 0) - return true; + unsigned long long * SizePtr = &Size; + if (Result == 416) + SizePtr = &JunkSize; - Size = strtoull(Val.c_str(), NULL, 10); - if (Size >= std::numeric_limits::max()) + *SizePtr = strtoull(Val.c_str(), NULL, 10); + if (*SizePtr >= std::numeric_limits::max()) return _error->Errno("HeaderLine", _("The HTTP server sent an invalid Content-Length header")); - else if (Size == 0) + else if (*SizePtr == 0) HaveContent = false; return true; } @@ -187,10 +188,7 @@ bool ServerState::HeaderLine(string Line) // §14.16 says 'byte-range-resp-spec' should be a '*' in case of 416 if (Result == 416 && sscanf(Val.c_str(), "bytes */%llu",&Size) == 1) - { - StartPos = 1; // ignore Content-Length, it would override Size - HaveContent = false; - } + ; // we got the expected filesize which is all we wanted else if (sscanf(Val.c_str(),"bytes %llu-%*u/%llu",&StartPos,&Size) != 2) return _error->Error(_("The HTTP server sent an invalid Content-Range header")); if ((unsigned long long)StartPos > Size) @@ -308,9 +306,15 @@ ServerMethod::DealWithHeaders(FetchResult &Res) if ((unsigned long long)SBuf.st_size == Server->Size) { // the file is completely downloaded, but was not moved + if (Server->HaveContent == true) + { + // Send to error page to dev/null + FileFd DevNull("/dev/null",FileFd::WriteExists); + Server->RunData(&DevNull); + } + Server->HaveContent = false; Server->StartPos = Server->Size; Server->Result = 200; - Server->HaveContent = false; } else if (unlink(Queue->DestFile.c_str()) == 0) { diff --git a/methods/server.h b/methods/server.h index f5e68d902..1b81e3549 100644 --- a/methods/server.h +++ b/methods/server.h @@ -34,7 +34,8 @@ struct ServerState char Code[360]; // These are some statistics from the last parsed header lines - unsigned long long Size; + unsigned long long Size; // size of the usable content (aka: the file) + unsigned long long JunkSize; // size of junk content (aka: server error pages) unsigned long long StartPos; time_t Date; bool HaveContent; @@ -71,7 +72,7 @@ struct ServerState RunHeadersResult RunHeaders(FileFd * const File, const std::string &Uri); bool Comp(URI Other) const {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;}; - virtual void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; Size = 0; + virtual void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; Size = 0; JunkSize = 0; StartPos = 0; Encoding = Closes; time(&Date); HaveContent = false; State = Header; Persistent = false; Pipeline = true;}; virtual bool WriteResponse(std::string const &Data) = 0; diff --git a/test/integration/framework b/test/integration/framework index df1942ff9..ac482a7a0 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1064,8 +1064,8 @@ acquire::cdrom::autodetect 0;" > rootdir/etc/apt/apt.conf.d/00cdrom } downloadfile() { - local PROTO="$(echo "$1" | cut -d':' -f 1 )" - apthelper -o Debug::Acquire::${PROTO}=1 \ + local PROTO="${1%%:*}" + apthelper -o Debug::Acquire::${PROTO}=1 -o Debug::pkgAcquire::Worker=1 \ download-file "$1" "$2" 2>&1 || true # only if the file exists the download was successful if [ -e "$2" ]; then @@ -1221,7 +1221,7 @@ testsuccess() { msgtest 'Test for successful execution of' "$*" fi local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testsuccess.output" - if $@ >${OUTPUT} 2>&1; then + if "$@" >${OUTPUT} 2>&1; then msgpass else echo >&2 diff --git a/test/integration/test-apt-helper b/test/integration/test-apt-helper index c749224ca..31e471677 100755 --- a/test/integration/test-apt-helper +++ b/test/integration/test-apt-helper @@ -10,34 +10,36 @@ configarchitecture "i386" changetohttpswebserver test_apt_helper_download() { - echo "foo" > aptarchive/foo + echo 'foo' > aptarchive/foo + echo 'bar' > aptarchive/foo2 msgtest 'apt-file download-file md5sum' - apthelper -qq download-file http://localhost:8080/foo foo2 MD5Sum:d3b07384d113edec49eaa6238ad5ff00 && msgpass || msgfail + testsuccess --nomsg apthelper download-file http://localhost:8080/foo foo2 MD5Sum:d3b07384d113edec49eaa6238ad5ff00 testfileequal foo2 'foo' msgtest 'apt-file download-file sha1' - apthelper -qq download-file http://localhost:8080/foo foo1 SHA1:f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 && msgpass || msgfail + testsuccess --nomsg apthelper download-file http://localhost:8080/foo foo1 SHA1:f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 testfileequal foo1 'foo' msgtest 'apt-file download-file sha256' - apthelper -qq download-file http://localhost:8080/foo foo3 SHA256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c && msgpass || msgfail + testsuccess --nomsg apthelper download-file http://localhost:8080/foo foo3 SHA256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c testfileequal foo3 'foo' msgtest 'apt-file download-file no-hash' - apthelper -qq download-file http://localhost:8080/foo foo4 && msgpass || msgfail + testsuccess --nomsg apthelper download-file http://localhost:8080/foo foo4 testfileequal foo4 'foo' msgtest 'apt-file download-file wrong hash' - if ! apthelper -qq download-file http://localhost:8080/foo foo5 MD5Sum:aabbcc 2>&1 2> download.stderr; then - msgpass - else - msgfail - fi - testfileequal download.stderr 'E: Failed to fetch http://localhost:8080/foo Hash Sum mismatch + testfailure --nomsg apthelper -qq download-file http://localhost:8080/foo foo5 MD5Sum:aabbcc + testfileequal rootdir/tmp/testfailure.output 'E: Failed to fetch http://localhost:8080/foo Hash Sum mismatch E: Download Failed' testfileequal foo5.FAILED 'foo' + + msgtest 'apt-file download-file md5sum sha1' + testsuccess --nomsg apthelper download-file http://localhost:8080/foo foo6 MD5Sum:d3b07384d113edec49eaa6238ad5ff00 http://localhost:8080/foo2 foo7 SHA1:e242ed3bffccdf271b7fbaf34ed72d089537b42f + testfileequal foo6 'foo' + testfileequal foo7 'bar' } test_apt_helper_detect_proxy() { diff --git a/test/integration/test-partial-file-support b/test/integration/test-partial-file-support index 5ab326def..160d451b6 100755 --- a/test/integration/test-partial-file-support +++ b/test/integration/test-partial-file-support @@ -24,13 +24,25 @@ testdownloadfile() { else msgpass fi - cat "$DOWNLOADLOG" | while read field hash; do + sed -e '/^ <- / s#%20# #g' -e '/^ <- / s#%0a#\n#g' "$DOWNLOADLOG" | grep '^.*-Hash: ' > receivedhashes.log + testsuccess test -s receivedhashes.log + local HASHES_OK=0 + local HASHES_BAD=0 + while read field hash; do local EXPECTED case "$field" in 'MD5Sum-Hash:') EXPECTED="$(md5sum "$TESTFILE" | cut -d' ' -f 1)";; 'SHA1-Hash:') EXPECTED="$(sha1sum "$TESTFILE" | cut -d' ' -f 1)";; 'SHA256-Hash:') EXPECTED="$(sha256sum "$TESTFILE" | cut -d' ' -f 1)";; 'SHA512-Hash:') EXPECTED="$(sha512sum "$TESTFILE" | cut -d' ' -f 1)";; + 'Checksum-FileSize-Hash:') + #filesize is too weak to check for != + if [ "$4" = '=' ]; then + EXPECTED="$(stat -c '%s' "$TESTFILE")" + else + continue + fi + ;; *) continue;; esac if [ "$4" = '=' ]; then @@ -40,15 +52,41 @@ testdownloadfile() { fi if [ "$EXPECTED" "$4" "$hash" ]; then msgpass + HASHES_OK=$((HASHES_OK+1)); else - cat >&2 "$DOWNLOADLOG" msgfail "expected: $EXPECTED ; got: $hash" + HASHES_BAD=$((HASHES_BAD+1)); fi - done + done < receivedhashes.log + msgtest 'At least one good hash and no bad ones' + if [ $HASHES_OK -eq 0 ] || [ $HASHES_BAD -ne 0 ]; then + cat >&2 "$DOWNLOADLOG" + msgfail + else + msgpass + fi } TESTFILE='aptarchive/testfile' cp -a ${TESTDIR}/framework $TESTFILE +cp -a ${TESTDIR}/framework "${TESTFILE}2" + +followuprequest() { + local DOWN='./testfile' + + copysource $TESTFILE 1M $DOWN + testdownloadfile 'completely downloaded file' "${1}/testfile" "$DOWN" '=' + testwebserverlaststatuscode '416' "$DOWNLOADLOG" + + copysource $TESTFILE 1M $DOWN + copysource "${TESTFILE}2" 20 "${DOWN}2" + msgtest 'Testing download of files with' 'completely downloaded file + partial file' + testsuccess --nomsg apthelper -o Debug::Acquire::${1%%:*}=1 -o Debug::pkgAcquire::Worker=1 \ + download-file "$1/testfile" "$DOWN" '' "$1/testfile2" "${DOWN}2" + testwebserverlaststatuscode '206' 'rootdir/tmp/testsuccess.output' + testsuccess diff -u "$TESTFILE" "${DOWN}" + testsuccess diff -u "${DOWN}" "${DOWN}2" +} testrun() { webserverconfig 'aptwebserver::support::range' 'true' @@ -65,9 +103,11 @@ testrun() { testdownloadfile 'invalid partial data' "${1}/testfile" './testfile' '!=' testwebserverlaststatuscode '206' "$DOWNLOADLOG" - copysource $TESTFILE 1M ./testfile - testdownloadfile 'completely downloaded file' "${1}/testfile" './testfile' '=' - testwebserverlaststatuscode '416' "$DOWNLOADLOG" + webserverconfig 'aptwebserver::closeOnError' 'false' + followuprequest "$1" + webserverconfig 'aptwebserver::closeOnError' 'true' + followuprequest "$1" + webserverconfig 'aptwebserver::closeOnError' 'false' copysource /dev/zero 1M ./testfile testdownloadfile 'too-big partial file' "${1}/testfile" './testfile' '=' @@ -85,8 +125,18 @@ testrun() { testwebserverlaststatuscode '200' "$DOWNLOADLOG" } +msgmsg 'http: Test with Content-Length' +webserverconfig 'aptwebserver::chunked-transfer-encoding' 'false' +testrun 'http://localhost:8080' +msgmsg 'http: Test with Transfer-Encoding: chunked' +webserverconfig 'aptwebserver::chunked-transfer-encoding' 'true' testrun 'http://localhost:8080' changetohttpswebserver +msgmsg 'https: Test with Content-Length' +webserverconfig 'aptwebserver::chunked-transfer-encoding' 'false' +testrun 'https://localhost:4433' +msgmsg 'https: Test with Transfer-Encoding: chunked' +webserverconfig 'aptwebserver::chunked-transfer-encoding' 'true' testrun 'https://localhost:4433' diff --git a/test/interactive-helper/aptwebserver.cc b/test/interactive-helper/aptwebserver.cc index 34476e1af..cd52da692 100644 --- a/test/interactive-helper/aptwebserver.cc +++ b/test/interactive-helper/aptwebserver.cc @@ -19,6 +19,8 @@ #include #include #include + +#include #include #include #include @@ -79,12 +81,21 @@ static char const * httpcodeToStr(int const httpcode) /*{{{*/ return NULL; } /*}}}*/ +static bool chunkedTransferEncoding(std::list const &headers) { + if (std::find(headers.begin(), headers.end(), "Transfer-Encoding: chunked") != headers.end()) + return true; + if (_config->FindB("aptwebserver::chunked-transfer-encoding", false) == true) + return true; + return false; +} static void addFileHeaders(std::list &headers, FileFd &data)/*{{{*/ { - std::ostringstream contentlength; - contentlength << "Content-Length: " << data.FileSize(); - headers.push_back(contentlength.str()); - + if (chunkedTransferEncoding(headers) == false) + { + std::ostringstream contentlength; + contentlength << "Content-Length: " << data.FileSize(); + headers.push_back(contentlength.str()); + } std::string lastmodified("Last-Modified: "); lastmodified.append(TimeRFC1123(data.ModificationTime())); headers.push_back(lastmodified); @@ -92,9 +103,12 @@ static void addFileHeaders(std::list &headers, FileFd &data)/*{{{*/ /*}}}*/ static void addDataHeaders(std::list &headers, std::string &data)/*{{{*/ { - std::ostringstream contentlength; - contentlength << "Content-Length: " << data.size(); - headers.push_back(contentlength.str()); + if (chunkedTransferEncoding(headers) == false) + { + std::ostringstream contentlength; + contentlength << "Content-Length: " << data.size(); + headers.push_back(contentlength.str()); + } } /*}}}*/ static bool sendHead(int const client, int const httpcode, std::list &headers)/*{{{*/ @@ -114,6 +128,9 @@ static bool sendHead(int const client, int const httpcode, std::list>> RESPONSE to " << client << " >>>" << std::endl; bool Success = true; for (std::list::const_iterator h = headers.begin(); @@ -130,25 +147,55 @@ static bool sendHead(int const client, int const httpcode, std::list const &headers, FileFd &data)/*{{{*/ { bool Success = true; + bool const chunked = chunkedTransferEncoding(headers); char buffer[500]; unsigned long long actual = 0; while ((Success &= data.Read(buffer, sizeof(buffer), &actual)) == true) { if (actual == 0) break; - Success &= FileFd::Write(client, buffer, actual); + + if (chunked == true) + { + std::string size; + strprintf(size, "%llX\r\n", actual); + Success &= FileFd::Write(client, size.c_str(), size.size()); + Success &= FileFd::Write(client, buffer, actual); + Success &= FileFd::Write(client, "\r\n", strlen("\r\n")); + } + else + Success &= FileFd::Write(client, buffer, actual); + } + if (chunked == true) + { + char const * const finish = "0\r\n\r\n"; + Success &= FileFd::Write(client, finish, strlen(finish)); } if (Success == false) - std::cerr << "SENDFILE: READ/WRITE ERROR to " << client << std::endl; + std::cerr << "SENDFILE:" << (chunked ? " CHUNKED" : "") << " READ/WRITE ERROR to " << client << std::endl; return Success; } /*}}}*/ -static bool sendData(int const client, std::string const &data) /*{{{*/ +static bool sendData(int const client, std::list const &headers, std::string const &data)/*{{{*/ { - if (FileFd::Write(client, data.c_str(), data.size()) == false) + if (chunkedTransferEncoding(headers) == true) + { + unsigned long long const ullsize = data.length(); + std::string size; + strprintf(size, "%llX\r\n", ullsize); + char const * const finish = "\r\n0\r\n\r\n"; + if (FileFd::Write(client, size.c_str(), size.length()) == false || + FileFd::Write(client, data.c_str(), ullsize) == false || + FileFd::Write(client, finish, strlen(finish)) == false) + { + std::cerr << "SENDDATA: CHUNK WRITE ERROR to " << client << std::endl; + return false; + } + } + else if (FileFd::Write(client, data.c_str(), data.size()) == false) { std::cerr << "SENDDATA: WRITE ERROR to " << client << std::endl; return false; @@ -157,34 +204,38 @@ static bool sendData(int const client, std::string const &data) /*{{{*/ } /*}}}*/ static void sendError(int const client, int const httpcode, std::string const &request,/*{{{*/ - bool content, std::string const &error = "") + bool const content, std::string const &error, std::list &headers) { - std::list headers; std::string response(""); response.append(httpcodeToStr(httpcode)).append(""); response.append("

").append(httpcodeToStr(httpcode)).append("

"); if (httpcode != 200) - { - if (error.empty() == false) - response.append("

Error: ").append(error).append("

"); - response.append("This error is a result of the request:
");
-   }
+      response.append("

Error: "); + else + response.append("

Success: "); + if (error.empty() == false) + response.append(error); + else + response.append(httpcodeToStr(httpcode)); + if (httpcode != 200) + response.append("

This error is a result of the request:
");
    else
-   {
-      if (error.empty() == false)
-	 response.append("

Success: ").append(error).append("

"); response.append("The successfully executed operation was requested by:
");
-   }
    response.append(request).append("
"); + if (httpcode != 200) + { + if (_config->FindB("aptwebserver::closeOnError", false) == true) + headers.push_back("Connection: close"); + } addDataHeaders(headers, response); sendHead(client, httpcode, headers); if (content == true) - sendData(client, response); + sendData(client, headers, response); } static void sendSuccess(int const client, std::string const &request, - bool content, std::string const &error = "") + bool const content, std::string const &error, std::list &headers) { - sendError(client, 200, request, content, error); + sendError(client, 200, request, content, error, headers); } /*}}}*/ static void sendRedirect(int const client, int const httpcode, std::string const &uri,/*{{{*/ @@ -221,7 +272,7 @@ static void sendRedirect(int const client, int const httpcode, std::string const headers.push_back(location); sendHead(client, httpcode, headers); if (content == true) - sendData(client, response); + sendData(client, headers, response); } /*}}}*/ static int filter_hidden_files(const struct dirent *a) /*{{{*/ @@ -263,16 +314,15 @@ static int grouped_alpha_case_sort(const struct dirent **a, const struct dirent } /*}}}*/ static void sendDirectoryListing(int const client, std::string const &dir,/*{{{*/ - std::string const &request, bool content) + std::string const &request, bool content, std::list &headers) { - std::list headers; std::ostringstream listing; struct dirent **namelist; int const counter = scandir(dir.c_str(), &namelist, filter_hidden_files, grouped_alpha_case_sort); if (counter == -1) { - sendError(client, 500, request, content); + sendError(client, 500, request, content, "scandir failed", headers); return; } @@ -311,18 +361,18 @@ static void sendDirectoryListing(int const client, std::string const &dir,/*{{{* addDataHeaders(headers, response); sendHead(client, 200, headers); if (content == true) - sendData(client, response); + sendData(client, headers, response); } /*}}}*/ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ std::string &filename, std::string ¶ms, bool &sendContent, - bool &closeConnection) + bool &closeConnection, std::list &headers) { if (strncmp(request.c_str(), "HEAD ", 5) == 0) sendContent = false; if (strncmp(request.c_str(), "GET ", 4) != 0) { - sendError(client, 501, request, true); + sendError(client, 501, request, true, "", headers); return false; } @@ -333,7 +383,7 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ if (lineend == std::string::npos || filestart == std::string::npos || fileend == std::string::npos || filestart == fileend) { - sendError(client, 500, request, sendContent, "Filename can't be extracted"); + sendError(client, 500, request, sendContent, "Filename can't be extracted", headers); return false; } @@ -345,14 +395,14 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ closeConnection = strcasecmp(LookupTag(request, "Connection", "Keep-Alive").c_str(), "close") == 0; else { - sendError(client, 500, request, sendContent, "Not a HTTP/1.{0,1} request"); + sendError(client, 500, request, sendContent, "Not a HTTP/1.{0,1} request", headers); return false; } filename = request.substr(filestart, fileend - filestart); if (filename.find(' ') != std::string::npos) { - sendError(client, 500, request, sendContent, "Filename contains an unencoded space"); + sendError(client, 500, request, sendContent, "Filename contains an unencoded space", headers); return false; } @@ -360,7 +410,7 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ if (host.empty() == true) { // RFC 2616 §14.23 requires Host - sendError(client, 400, request, sendContent, "Host header is required"); + sendError(client, 400, request, sendContent, "Host header is required", headers); return false; } host = "http://" + host; @@ -371,7 +421,7 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ { if (absolute.find("uri") == std::string::npos) { - sendError(client, 400, request, sendContent, "Request is absoluteURI, but configured to not accept that"); + sendError(client, 400, request, sendContent, "Request is absoluteURI, but configured to not accept that", headers); return false; } // strip the host from the request to make it an absolute path @@ -379,7 +429,7 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ } else if (absolute.find("path") == std::string::npos) { - sendError(client, 400, request, sendContent, "Request is absolutePath, but configured to not accept that"); + sendError(client, 400, request, sendContent, "Request is absolutePath, but configured to not accept that", headers); return false; } @@ -398,7 +448,8 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ filename.find_first_of("\r\n\t\f\v") != std::string::npos || filename.find("/../") != std::string::npos) { - sendError(client, 400, request, sendContent, "Filename contains illegal character (sequence)"); + std::list headers; + sendError(client, 400, request, sendContent, "Filename contains illegal character (sequence)", headers); return false; } @@ -434,46 +485,45 @@ static bool parseFirstLine(int const client, std::string const &request,/*{{{*/ return true; } /*}}}*/ -static bool handleOnTheFlyReconfiguration(int const client, std::string const &request, std::vector const &parts)/*{{{*/ +static bool handleOnTheFlyReconfiguration(int const client, std::string const &request,/*{{{*/ + std::vector parts, std::list &headers) { size_t const pcount = parts.size(); if (pcount == 4 && parts[1] == "set") { _config->Set(parts[2], parts[3]); - sendSuccess(client, request, true, "Option '" + parts[2] + "' was set to '" + parts[3] + "'!"); + sendSuccess(client, request, true, "Option '" + parts[2] + "' was set to '" + parts[3] + "'!", headers); return true; } else if (pcount == 4 && parts[1] == "find") { - std::list headers; std::string response = _config->Find(parts[2], parts[3]); addDataHeaders(headers, response); sendHead(client, 200, headers); - sendData(client, response); + sendData(client, headers, response); return true; } else if (pcount == 3 && parts[1] == "find") { - std::list headers; if (_config->Exists(parts[2]) == true) { std::string response = _config->Find(parts[2]); addDataHeaders(headers, response); sendHead(client, 200, headers); - sendData(client, response); + sendData(client, headers, response); return true; } - sendError(client, 404, request, "Requested Configuration option doesn't exist."); + sendError(client, 404, request, true, "Requested Configuration option doesn't exist", headers); return false; } else if (pcount == 3 && parts[1] == "clear") { _config->Clear(parts[2]); - sendSuccess(client, request, true, "Option '" + parts[2] + "' was cleared."); + sendSuccess(client, request, true, "Option '" + parts[2] + "' was cleared.", headers); return true; } - sendError(client, 400, request, true, "Unknown on-the-fly configuration request"); + sendError(client, 400, request, true, "Unknown on-the-fly configuration request", headers); return false; } /*}}}*/ @@ -482,18 +532,22 @@ static void * handleClient(void * voidclient) /*{{{*/ int client = *((int*)(voidclient)); std::clog << "ACCEPT client " << client << std::endl; std::vector messages; - while (ReadMessages(client, messages)) + bool closeConnection = false; + std::list headers; + while (closeConnection == false && ReadMessages(client, messages)) { - bool closeConnection = false; + // if we announced a closing, do the close + if (std::find(headers.begin(), headers.end(), std::string("Connection: close")) != headers.end()) + break; + headers.clear(); for (std::vector::const_iterator m = messages.begin(); m != messages.end() && closeConnection == false; ++m) { std::clog << ">>> REQUEST from " << client << " >>>" << std::endl << *m << std::endl << "<<<<<<<<<<<<<<<<" << std::endl; - std::list headers; std::string filename; std::string params; bool sendContent = true; - if (parseFirstLine(client, *m, filename, params, sendContent, closeConnection) == false) + if (parseFirstLine(client, *m, filename, params, sendContent, closeConnection, headers) == false) continue; // special webserver command request @@ -502,7 +556,7 @@ static void * handleClient(void * voidclient) /*{{{*/ std::vector parts = VectorizeString(filename, '/'); if (parts[0] == "_config") { - handleOnTheFlyReconfiguration(client, *m, parts); + handleOnTheFlyReconfiguration(client, *m, parts, headers); continue; } } @@ -534,7 +588,7 @@ static void * handleClient(void * voidclient) /*{{{*/ { char error[300]; regerror(res, pattern, error, sizeof(error)); - sendError(client, 500, *m, sendContent, error); + sendError(client, 500, *m, sendContent, error, headers); continue; } if (regexec(pattern, filename.c_str(), 0, 0, 0) == 0) @@ -553,7 +607,7 @@ static void * handleClient(void * voidclient) /*{{{*/ if (_config->FindB("aptwebserver::support::http", true) == false && LookupTag(*m, "Host").find(":4433") == std::string::npos) { - sendError(client, 400, *m, sendContent, "HTTP disabled, all requests must be HTTPS"); + sendError(client, 400, *m, sendContent, "HTTP disabled, all requests must be HTTPS", headers); continue; } else if (RealFileExists(filename) == true) @@ -609,17 +663,16 @@ static void * handleClient(void * voidclient) /*{{{*/ headers.push_back(contentrange.str()); sendHead(client, 206, headers); if (sendContent == true) - sendFile(client, data); + sendFile(client, headers, data); continue; } else { - headers.push_back("Content-Length: 0"); std::ostringstream contentrange; contentrange << "Content-Range: bytes */" << filesize; headers.push_back(contentrange.str()); - sendHead(client, 416, headers); - continue; + sendError(client, 416, *m, sendContent, "", headers); + break; } } } @@ -628,22 +681,20 @@ static void * handleClient(void * voidclient) /*{{{*/ addFileHeaders(headers, data); sendHead(client, 200, headers); if (sendContent == true) - sendFile(client, data); + sendFile(client, headers, data); } else if (DirectoryExists(filename) == true) { if (filename[filename.length()-1] == '/') - sendDirectoryListing(client, filename, *m, sendContent); + sendDirectoryListing(client, filename, *m, sendContent, headers); else sendRedirect(client, 301, filename.append("/"), *m, sendContent); } else - sendError(client, 404, *m, sendContent); + sendError(client, 404, *m, sendContent, "", headers); } _error->DumpErrors(std::cerr); messages.clear(); - if (closeConnection == true) - break; } close(client); std::clog << "CLOSE client " << client << std::endl; -- cgit v1.2.3-70-g09d2 From e18f6133b254db9e1dc7b202366b067b15a68123 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 10 Dec 2014 22:26:59 +0100 Subject: do not make PTY slave the controlling terminal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we have no controlling terminal opening a terminal will make this terminal our controller, which is a serious problem if this happens to be the pseudo terminal we created to run dpkg in as we will close this terminal at the end hanging ourself up in the process… The offending open is the one we do to have at least one slave fd open all the time, but for good measure, we apply the flag also to the slave fd opening in the child process as we set the controlling terminal explicitely here. This is a regression from 150bdc9ca5d656f9fba94d37c5f4f183b02bd746 with the slight twist that this usecase was silently broken before in that it wasn't logging the output in term.log (as a pseudo terminal wasn't created). Closes: 772641 --- apt-pkg/deb/dpkgpm.cc | 4 +- test/integration/framework | 2 +- .../test-no-fds-leaked-to-maintainer-scripts | 109 +++++++++++++-------- 3 files changed, 70 insertions(+), 45 deletions(-) (limited to 'test/integration/framework') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index e36a52c3e..93a007d14 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1131,7 +1131,7 @@ void pkgDPkgPM::StartPtyMagic() on kfreebsd we get an incorrect ("step like") output then while it has no problem with closing all references… so to avoid platform specific code here we combine both and be happy once more */ - d->protect_slave_from_dying = open(d->slave, O_RDWR | O_CLOEXEC); + d->protect_slave_from_dying = open(d->slave, O_RDWR | O_CLOEXEC | O_NOCTTY); } } } @@ -1163,7 +1163,7 @@ void pkgDPkgPM::SetupSlavePtyMagic() if (setsid() == -1) _error->FatalE("setsid", "Starting a new session for child failed!"); - int const slaveFd = open(d->slave, O_RDWR); + int const slaveFd = open(d->slave, O_RDWR | O_NOCTTY); if (slaveFd == -1) _error->FatalE("open", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); else if (ioctl(slaveFd, TIOCSCTTY, 0) < 0) diff --git a/test/integration/framework b/test/integration/framework index ac482a7a0..9e183057f 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -102,7 +102,7 @@ runapt() { local CMD="$1" shift case $CMD in - sh|aptitude|*/*) ;; + sh|aptitude|*/*|command) ;; *) CMD="${BUILDDIRECTORY}/$CMD";; esac MALLOC_PERTURB_=21 MALLOC_CHECK_=2 APT_CONFIG="$(getaptconfig)" LD_LIBRARY_PATH=${BUILDDIRECTORY} $CMD "$@" diff --git a/test/integration/test-no-fds-leaked-to-maintainer-scripts b/test/integration/test-no-fds-leaked-to-maintainer-scripts index 3c6457cab..6eb033055 100755 --- a/test/integration/test-no-fds-leaked-to-maintainer-scripts +++ b/test/integration/test-no-fds-leaked-to-maintainer-scripts @@ -5,7 +5,7 @@ TESTDIR=$(readlink -f $(dirname $0)) . $TESTDIR/framework setupenvironment -configarchitecture 'native' +configarchitecture 'amd64' 'i386' configdpkgnoopchroot setupsimplenativepackage "fdleaks" 'all' '1.0' 'unstable' @@ -17,58 +17,83 @@ done buildpackage "$BUILDDIR" 'unstable' 'main' 'native' rm -rf "$BUILDDIR" +PKGNAME='fdleaks:all' +if ! dpkg-checkbuilddeps -d 'dpkg (>= 1.16.2)' /dev/null >/dev/null 2>&1; then + PKGNAME='fdleaks' +fi + setupaptarchive rm -f rootdir/var/log/dpkg.log rootdir/var/log/apt/term.log testsuccess aptget install -y fdleaks -qq < /dev/null -msgtest 'Check if fds were not' 'leaked' -if [ "$(grep 'root root' rootdir/tmp/testsuccess.output | wc -l)" = '8' ]; then - msgpass -else - echo - cat rootdir/tmp/testsuccess.output - msgfail -fi -cp rootdir/tmp/testsuccess.output terminal.output -tail -n +3 rootdir/var/log/apt/term.log | head -n -1 > terminal.log -testfileequal 'terminal.log' "$(cat terminal.output)" +checkfdleak() { + msgtest 'Check if fds were not' 'leaked' + if [ "$(grep 'root root' rootdir/tmp/testsuccess.output | wc -l)" = "$1" ]; then + msgpass + else + echo + cat rootdir/tmp/testsuccess.output + msgfail + fi +} +checkinstall() { + checkfdleak 8 + + cp rootdir/tmp/testsuccess.output terminal.output + tail -n +3 rootdir/var/log/apt/term.log | head -n -1 > terminal.log + testfileequal 'terminal.log' "$(cat terminal.output)" -testequal 'startup archives unpack -install fdleaks:all 1.0 -status half-installed fdleaks:all 1.0 -status unpacked fdleaks:all 1.0 -status unpacked fdleaks:all 1.0 + testequal "startup archives unpack +install $PKGNAME 1.0 +status half-installed $PKGNAME 1.0 +status unpacked $PKGNAME 1.0 +status unpacked $PKGNAME 1.0 startup packages configure -configure fdleaks:all 1.0 -status unpacked fdleaks:all 1.0 -status half-configured fdleaks:all 1.0 -status installed fdleaks:all 1.0' cut -f 3- -d' ' rootdir/var/log/dpkg.log +configure $PKGNAME 1.0 +status unpacked $PKGNAME 1.0 +status half-configured $PKGNAME 1.0 +status installed $PKGNAME 1.0" cut -f 3- -d' ' rootdir/var/log/dpkg.log +} +checkinstall rm -f rootdir/var/log/dpkg.log rootdir/var/log/apt/term.log testsuccess aptget purge -y fdleaks -qq -msgtest 'Check if fds were not' 'leaked' -if [ "$(grep 'root root' rootdir/tmp/testsuccess.output | wc -l)" = '12' ]; then +checkpurge() { + checkfdleak 12 + + cp rootdir/tmp/testsuccess.output terminal.output + tail -n +3 rootdir/var/log/apt/term.log | head -n -1 > terminal.log + testfileequal 'terminal.log' "$(cat terminal.output)" + + testequal "startup packages purge +status installed $PKGNAME 1.0 +remove $PKGNAME 1.0 +status half-configured $PKGNAME 1.0 +status half-installed $PKGNAME 1.0 +status config-files $PKGNAME 1.0 +purge $PKGNAME 1.0 +status config-files $PKGNAME 1.0 +status config-files $PKGNAME 1.0 +status config-files $PKGNAME 1.0 +status config-files $PKGNAME 1.0 +status config-files $PKGNAME 1.0 +status not-installed $PKGNAME " cut -f 3- -d' ' rootdir/var/log/dpkg.log +} +checkpurge + +msgtest 'setsid provided is new enough to support' '-w' +if dpkg-checkbuilddeps -d 'util-linux (>= 2.24.2-1)' /dev/null >/dev/null 2>&1; then msgpass else - echo - cat rootdir/tmp/testsuccess.output - msgfail + msgskip "$(command dpkg -l util-linux)" + exit fi -cp rootdir/tmp/testsuccess.output terminal.output -tail -n +3 rootdir/var/log/apt/term.log | head -n -1 > terminal.log -testfileequal 'terminal.log' "$(cat terminal.output)" -testequal 'startup packages purge -status installed fdleaks:all 1.0 -remove fdleaks:all 1.0 -status half-configured fdleaks:all 1.0 -status half-installed fdleaks:all 1.0 -status config-files fdleaks:all 1.0 -purge fdleaks:all 1.0 -status config-files fdleaks:all 1.0 -status config-files fdleaks:all 1.0 -status config-files fdleaks:all 1.0 -status config-files fdleaks:all 1.0 -status config-files fdleaks:all 1.0 -status not-installed fdleaks:all ' cut -f 3- -d' ' rootdir/var/log/dpkg.log +rm -f rootdir/var/log/dpkg.log rootdir/var/log/apt/term.log +testsuccess runapt command setsid -w "${BUILDDIRECTORY}/apt-get" install -y fdleaks -qq < /dev/null +checkinstall + +rm -f rootdir/var/log/dpkg.log rootdir/var/log/apt/term.log +testsuccess runapt command setsid -w "${BUILDDIRECTORY}/apt-get" purge -y fdleaks -qq +checkpurge -- cgit v1.2.3-70-g09d2 From a2a75ff4516f7609f4c55b42270abb8d08943c60 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 18 Nov 2014 19:53:56 +0100 Subject: always run 'dpkg --configure -a' at the end of our dpkg callings dpkg checks now for dependencies before running triggers, so that packages can now end up in trigger states (especially those we are not touching at all with our calls) after apt is done running. The solution to this is trivial: Just tell dpkg to configure everything after we have (supposely) configured everything already. In the worst case this means dpkg will have to run a bunch of triggers, usually it will just do nothing though. The code to make this happen was already available, so we just flip a config option here to cause it to be run. This way we can keep pretending that triggers are an implementation detail of dpkg. --triggers-only would supposely work as well, but --configure is more robust in regards to future changes to dpkg and something we will hopefully make use of in future versions anyway (as it was planed at the time this and related options were implemented). Note that dpkg currently has a workaround implemented to allow upgrades to jessie to be clean, so that the test works before and after. Also note that test (compared to the one in the bug) drops the await test as its is considered a loop by dpkg now. Closes: 769609 --- apt-pkg/deb/dpkgpm.cc | 9 ++- test/integration/framework | 25 ++++---- test/integration/test-apt-progress-fd | 67 ++++++++++--------- test/integration/test-apt-progress-fd-deb822 | 18 ++++-- test/integration/test-apt-progress-fd-error | 2 +- ...est-bug-769609-triggers-still-pending-after-run | 75 ++++++++++++++++++++++ .../test-no-fds-leaked-to-maintainer-scripts | 6 +- 7 files changed, 146 insertions(+), 56 deletions(-) create mode 100755 test/integration/test-bug-769609-triggers-still-pending-after-run (limited to 'test/integration/framework') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 93a007d14..d54b7b50f 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1047,6 +1047,12 @@ void pkgDPkgPM::BuildPackagesProgressMap() PackagesTotal++; } } + /* one extra: We don't want the progress bar to reach 100%, especially not + if we call dpkg --configure --pending and process a bunch of triggers + while showing 100%. Also, spindown takes a while, so never reaching 100% + is way more correct than reaching 100% while still doing stuff even if + doing it this way is slightly bending the rules */ + ++PackagesTotal; } /*}}}*/ #if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) @@ -1280,9 +1286,8 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) // support subpressing of triggers processing for special // cases like d-i that runs the triggers handling manually - bool const SmartConf = (_config->Find("PackageManager::Configure", "all") != "all"); bool const TriggersPending = _config->FindB("DPkg::TriggersPending", false); - if (_config->FindB("DPkg::ConfigurePending", SmartConf) == true) + if (_config->FindB("DPkg::ConfigurePending", true) == true) List.push_back(Item(Item::ConfigurePending, PkgIterator())); // for the progress diff --git a/test/integration/framework b/test/integration/framework index 9e183057f..c9445065b 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1178,10 +1178,13 @@ testnopackage() { fi } -testdpkginstalled() { - msgtest "Test for correctly installed package(s) with" "dpkg -l $*" - local PKGS="$(dpkg -l "$@" 2>/dev/null | grep '^i' | wc -l)" - if [ "$PKGS" != $# ]; then +testdpkgstatus() { + local STATE="$1" + local NR="$2" + shift 2 + msgtest "Test that $NR package(s) are in state $STATE with" "dpkg -l $*" + local PKGS="$(dpkg -l "$@" 2>/dev/null | grep "^${STATE}" | wc -l)" + if [ "$PKGS" != $NR ]; then echo >&2 $PKGS dpkg -l "$@" | grep '^[a-z]' >&2 msgfail @@ -1190,16 +1193,12 @@ testdpkginstalled() { fi } +testdpkginstalled() { + testdpkgstatus 'ii' "$#" "$@" +} + testdpkgnotinstalled() { - msgtest "Test for correctly not-installed package(s) with" "dpkg -l $*" - local PKGS="$(dpkg -l "$@" 2> /dev/null | grep '^i' | wc -l)" - if [ "$PKGS" != 0 ]; then - echo - dpkg -l "$@" | grep '^[a-z]' >&2 - msgfail - else - msgpass - fi + testdpkgstatus 'ii' '0' "$@" } testmarkedauto() { diff --git a/test/integration/test-apt-progress-fd b/test/integration/test-apt-progress-fd index d72e7e72d..68cc0439c 100755 --- a/test/integration/test-apt-progress-fd +++ b/test/integration/test-apt-progress-fd @@ -19,13 +19,14 @@ testequal "dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:0:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Installing testing (amd64) -pmstatus:testing:20:Preparing testing (amd64) -pmstatus:testing:40:Unpacking testing (amd64) -pmstatus:testing:60:Preparing to configure testing (amd64) -pmstatus:dpkg-exec:60:Running dpkg -pmstatus:testing:60:Configuring testing (amd64) -pmstatus:testing:80:Configuring testing (amd64) -pmstatus:testing:100:Installed testing (amd64)" cat apt-progress.log +pmstatus:testing:16.6667:Preparing testing (amd64) +pmstatus:testing:33.3333:Unpacking testing (amd64) +pmstatus:testing:50:Preparing to configure testing (amd64) +pmstatus:dpkg-exec:50:Running dpkg +pmstatus:testing:50:Configuring testing (amd64) +pmstatus:testing:66.6667:Configuring testing (amd64) +pmstatus:testing:83.3333:Installed testing (amd64) +pmstatus:dpkg-exec:83.3333:Running dpkg" cat apt-progress.log # upgrade exec 3> apt-progress.log @@ -34,13 +35,14 @@ testequal "dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:0:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Installing testing (amd64) -pmstatus:testing:20:Preparing testing (amd64) -pmstatus:testing:40:Unpacking testing (amd64) -pmstatus:testing:60:Preparing to configure testing (amd64) -pmstatus:dpkg-exec:60:Running dpkg -pmstatus:testing:60:Configuring testing (amd64) -pmstatus:testing:80:Configuring testing (amd64) -pmstatus:testing:100:Installed testing (amd64)" cat apt-progress.log +pmstatus:testing:16.6667:Preparing testing (amd64) +pmstatus:testing:33.3333:Unpacking testing (amd64) +pmstatus:testing:50:Preparing to configure testing (amd64) +pmstatus:dpkg-exec:50:Running dpkg +pmstatus:testing:50:Configuring testing (amd64) +pmstatus:testing:66.6667:Configuring testing (amd64) +pmstatus:testing:83.3333:Installed testing (amd64) +pmstatus:dpkg-exec:83.3333:Running dpkg" cat apt-progress.log # reinstall exec 3> apt-progress.log @@ -49,22 +51,24 @@ testequal "dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:0:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Installing testing (amd64) -pmstatus:testing:20:Preparing testing (amd64) -pmstatus:testing:40:Unpacking testing (amd64) -pmstatus:testing:60:Preparing to configure testing (amd64) -pmstatus:dpkg-exec:60:Running dpkg -pmstatus:testing:60:Configuring testing (amd64) -pmstatus:testing:80:Configuring testing (amd64) -pmstatus:testing:100:Installed testing (amd64)" cat apt-progress.log +pmstatus:testing:16.6667:Preparing testing (amd64) +pmstatus:testing:33.3333:Unpacking testing (amd64) +pmstatus:testing:50:Preparing to configure testing (amd64) +pmstatus:dpkg-exec:50:Running dpkg +pmstatus:testing:50:Configuring testing (amd64) +pmstatus:testing:66.6667:Configuring testing (amd64) +pmstatus:testing:83.3333:Installed testing (amd64) +pmstatus:dpkg-exec:83.3333:Running dpkg" cat apt-progress.log # and remove exec 3> apt-progress.log testsuccess aptget remove testing -y -o APT::Status-Fd=3 testequal "pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Removing testing (amd64) -pmstatus:testing:33.3333:Preparing for removal of testing (amd64) -pmstatus:testing:66.6667:Removing testing (amd64) -pmstatus:testing:100:Removed testing (amd64)" cat apt-progress.log +pmstatus:testing:25:Preparing for removal of testing (amd64) +pmstatus:testing:50:Removing testing (amd64) +pmstatus:testing:75:Removed testing (amd64) +pmstatus:dpkg-exec:75:Running dpkg" cat apt-progress.log # install non-native and ensure we get proper progress info exec 3> apt-progress.log @@ -75,12 +79,13 @@ testequal "dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:0:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing2:0:Installing testing2 (i386) -pmstatus:testing2:20:Preparing testing2 (i386) -pmstatus:testing2:40:Unpacking testing2 (i386) -pmstatus:testing2:60:Preparing to configure testing2 (i386) -pmstatus:dpkg-exec:60:Running dpkg -pmstatus:testing2:60:Configuring testing2 (i386) -pmstatus:testing2:80:Configuring testing2 (i386) -pmstatus:testing2:100:Installed testing2 (i386)" cat apt-progress.log +pmstatus:testing2:16.6667:Preparing testing2 (i386) +pmstatus:testing2:33.3333:Unpacking testing2 (i386) +pmstatus:testing2:50:Preparing to configure testing2 (i386) +pmstatus:dpkg-exec:50:Running dpkg +pmstatus:testing2:50:Configuring testing2 (i386) +pmstatus:testing2:66.6667:Configuring testing2 (i386) +pmstatus:testing2:83.3333:Installed testing2 (i386) +pmstatus:dpkg-exec:83.3333:Running dpkg" cat apt-progress.log rm -f apt-progress*.log diff --git a/test/integration/test-apt-progress-fd-deb822 b/test/integration/test-apt-progress-fd-deb822 index 9d227942d..badc985e4 100755 --- a/test/integration/test-apt-progress-fd-deb822 +++ b/test/integration/test-apt-progress-fd-deb822 @@ -27,37 +27,41 @@ Message: Installing testing (amd64) Status: progress Package: testing:amd64 -Percent: 20 +Percent: 16.6667 Message: Preparing testing (amd64) Status: progress Package: testing:amd64 -Percent: 40 +Percent: 33.3333 Message: Unpacking testing (amd64) Status: progress Package: testing:amd64 -Percent: 60 +Percent: 50 Message: Preparing to configure testing (amd64) Status: progress -Percent: 60 +Percent: 50 Message: Running dpkg Status: progress Package: testing:amd64 -Percent: 60 +Percent: 50 Message: Configuring testing (amd64) Status: progress Package: testing:amd64 -Percent: 80 +Percent: 66.6667 Message: Configuring testing (amd64) Status: progress Package: testing:amd64 -Percent: 100 +Percent: 83.3333 Message: Installed testing (amd64) + +Status: progress +Percent: 83.3333 +Message: Running dpkg " cat apt-progress.log diff --git a/test/integration/test-apt-progress-fd-error b/test/integration/test-apt-progress-fd-error index a47095b9b..632300765 100755 --- a/test/integration/test-apt-progress-fd-error +++ b/test/integration/test-apt-progress-fd-error @@ -18,7 +18,7 @@ setupaptarchive exec 3> apt-progress.log testfailure aptget install foo1 foo2 -y -o APT::Status-Fd=3 msgtest "Ensure correct error message" -if grep -q "aptarchive/pool/foo2_0.8.15_amd64.deb:40:trying to overwrite '/usr/bin/file-conflict', which is also in package foo1 0.8.15" apt-progress.log; then +if grep -q "aptarchive/pool/foo2_0.8.15_amd64.deb:36.3636:trying to overwrite '/usr/bin/file-conflict', which is also in package foo1 0.8.15" apt-progress.log; then msgpass else cat apt-progress.log diff --git a/test/integration/test-bug-769609-triggers-still-pending-after-run b/test/integration/test-bug-769609-triggers-still-pending-after-run new file mode 100755 index 000000000..146fa766b --- /dev/null +++ b/test/integration/test-bug-769609-triggers-still-pending-after-run @@ -0,0 +1,75 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework + +setupenvironment +configarchitecture 'amd64' + +msgtest 'Check if installed dpkg supports' 'noawait trigger' +if dpkg-checkbuilddeps -d 'dpkg (>= 1.16.1)' /dev/null; then + msgpass +else + msgskip 'dpkg version too old' + exit 0 +fi +configdpkgnoopchroot + +buildtriggerpackages() { + local TYPE="$1" + setupsimplenativepackage "triggerable-$TYPE" 'all' '1.0' 'unstable' "Depends: trigdepends-$TYPE" + BUILDDIR="incoming/triggerable-${TYPE}-1.0" + cat >${BUILDDIR}/debian/postinst < ${BUILDDIR}/debian/triggers + buildpackage "$BUILDDIR" 'unstable' 'main' 'native' + rm -rf "$BUILDDIR" + buildsimplenativepackage "trigdepends-$TYPE" 'all' '1.0' 'unstable' +} + +#buildtriggerpackages 'interest' +buildtriggerpackages 'interest-noawait' +buildsimplenativepackage "trigstuff" 'all' '1.0' 'unstable' + +setupaptarchive + +runtests() { + local TYPE="$1" + msgmsg 'Working with trigger type' "$TYPE" + testsuccess aptget install triggerable-$TYPE -y + cp rootdir/tmp/testsuccess.output terminal.output + testsuccess grep '^REWRITE ' terminal.output + testdpkginstalled triggerable-$TYPE trigdepends-$TYPE + + testsuccess aptget install trigdepends-$TYPE -y --reinstall + cp rootdir/tmp/testsuccess.output terminal.output + testsuccess grep '^REWRITE ' terminal.output + testsuccess grep ' root root ' terminal.output + testdpkginstalled triggerable-$TYPE trigdepends-$TYPE + + testsuccess aptget install trigstuff -y + cp rootdir/tmp/testsuccess.output terminal.output + testsuccess grep '^REWRITE ' terminal.output + testsuccess grep ' root root ' terminal.output + testdpkginstalled triggerable-$TYPE trigdepends-$TYPE trigstuff + + testsuccess aptget purge trigstuff -y + cp rootdir/tmp/testsuccess.output terminal.output + testsuccess grep '^REWRITE ' terminal.output + testsuccess grep ' root root ' terminal.output + testdpkginstalled triggerable-$TYPE trigdepends-$TYPE + testdpkgnotinstalled trigstuff + + testsuccess aptget purge trigdepends-$TYPE -y + cp rootdir/tmp/testsuccess.output terminal.output + testfailure grep '^REWRITE ' terminal.output + testfailure grep ' root root ' terminal.output + testdpkgnotinstalled triggerable-$TYPE trigdepends-$TYPE +} +#runtests 'interest' +runtests 'interest-noawait' diff --git a/test/integration/test-no-fds-leaked-to-maintainer-scripts b/test/integration/test-no-fds-leaked-to-maintainer-scripts index 6eb033055..7d0c1c6c1 100755 --- a/test/integration/test-no-fds-leaked-to-maintainer-scripts +++ b/test/integration/test-no-fds-leaked-to-maintainer-scripts @@ -53,7 +53,8 @@ startup packages configure configure $PKGNAME 1.0 status unpacked $PKGNAME 1.0 status half-configured $PKGNAME 1.0 -status installed $PKGNAME 1.0" cut -f 3- -d' ' rootdir/var/log/dpkg.log +status installed $PKGNAME 1.0 +startup packages configure" cut -f 3- -d' ' rootdir/var/log/dpkg.log } checkinstall @@ -78,7 +79,8 @@ status config-files $PKGNAME 1.0 status config-files $PKGNAME 1.0 status config-files $PKGNAME 1.0 status config-files $PKGNAME 1.0 -status not-installed $PKGNAME " cut -f 3- -d' ' rootdir/var/log/dpkg.log +status not-installed $PKGNAME +startup packages configure" cut -f 3- -d' ' rootdir/var/log/dpkg.log } checkpurge -- cgit v1.2.3-70-g09d2 From 31be38d205406d4c756684e20b93d62c4701e091 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 9 Jan 2015 01:03:31 +0100 Subject: 128 KiB DSC files ought to be enough for everyone Your mileage may vary, but don't worry: There is more than one way to do it, but our one size fits all is not a bigger hammer, but an entire roundhouse kick! So brace yourself for the tl;dr: The limit is gone.* Beware: This fixes also the problem that a double newline is unconditionally added 'later' which is an overcommitment in case the dsc filesize is limit-2 <= x <= limit. * limited to numbers fitting into an unsigned long long. Closes: 774893 --- ftparchive/cachedb.cc | 6 ++-- ftparchive/sources.cc | 41 ++++++++++++++++-------- ftparchive/sources.h | 26 ++++++--------- ftparchive/writer.cc | 12 ++----- test/integration/framework | 2 +- test/integration/test-apt-ftparchive-src-cachedb | 4 --- 6 files changed, 42 insertions(+), 49 deletions(-) (limited to 'test/integration/framework') diff --git a/ftparchive/cachedb.cc b/ftparchive/cachedb.cc index 0901492f7..c73a64fb7 100644 --- a/ftparchive/cachedb.cc +++ b/ftparchive/cachedb.cc @@ -328,12 +328,12 @@ bool CacheDB::LoadSource() if (Dsc.Read(FileName) == false) return false; - if (Dsc.Data == 0) + if (Dsc.Length == 0) return _error->Error(_("Failed to read .dsc")); - + // Write back the control information InitQuerySource(); - if (Put(Dsc.Data, Dsc.Length) == true) + if (Put(Dsc.Data.c_str(), Dsc.Length) == true) CurStat.Flags |= FlSource; return true; diff --git a/ftparchive/sources.cc b/ftparchive/sources.cc index d0878a70a..ab976b490 100644 --- a/ftparchive/sources.cc +++ b/ftparchive/sources.cc @@ -1,5 +1,5 @@ #include -#include +#include // for memcpy #include @@ -9,17 +9,19 @@ #include "sources.h" -bool DscExtract::TakeDsc(const void *newData, unsigned long newSize) +bool DscExtract::TakeDsc(const void *newData, unsigned long long newSize) { - if(newSize > maxSize) - return _error->Error("DSC data is too large %lu!", newSize); - if (newSize == 0) { + // adding two newlines 'off record' for pkgTagSection.Scan() calls + Data = "\n\n"; Length = 0; return true; } - memcpy(Data, newData, newSize); + + Data = std::string((const char*)newData, newSize); + // adding two newlines 'off record' for pkgTagSection.Scan() calls + Data.append("\n\n"); Length = newSize; return true; @@ -27,20 +29,31 @@ bool DscExtract::TakeDsc(const void *newData, unsigned long newSize) bool DscExtract::Read(std::string FileName) { + Data.clear(); + Length = 0; + FileFd F; if (OpenMaybeClearSignedFile(FileName, F) == false) return false; - - unsigned long long const FSize = F.FileSize(); - if(FSize > maxSize) - return _error->Error("DSC file '%s' is too large!",FileName.c_str()); - - if (F.Read(Data, FSize) == false) - return false; - Length = FSize; IsClearSigned = (FileName != F.Name()); + std::ostringstream data; + char buffer[1024]; + do { + unsigned long long actual = 0; + if (F.Read(buffer, sizeof(buffer)-1, &actual) == false) + return _error->Errno("read", "Failed to read dsc file %s", FileName.c_str()); + if (actual == 0) + break; + Length += actual; + buffer[actual] = '\0'; + data << buffer; + } while(true); + + // adding two newlines 'off record' for pkgTagSection.Scan() calls + data << "\n\n"; + Data = data.str(); return true; } diff --git a/ftparchive/sources.h b/ftparchive/sources.h index 91e0b1376..a125ec6a4 100644 --- a/ftparchive/sources.h +++ b/ftparchive/sources.h @@ -3,29 +3,21 @@ #include -class DscExtract +#include + +class DscExtract { public: - //FIXME: do we really need to enforce a maximum size of the dsc file? - static const int maxSize = 128*1024; - - char *Data; + std::string Data; pkgTagSection Section; - unsigned long Length; + unsigned long long Length; bool IsClearSigned; - bool TakeDsc(const void *Data, unsigned long Size); + bool TakeDsc(const void *Data, unsigned long long Size); bool Read(std::string FileName); - - DscExtract() : Data(0), Length(0) { - Data = new char[maxSize]; - }; - ~DscExtract() { - if(Data != NULL) { - delete [] Data; - Data = NULL; - } - }; + + DscExtract() : Length(0), IsClearSigned(false) {}; + ~DscExtract() {}; }; diff --git a/ftparchive/writer.cc b/ftparchive/writer.cc index 7c1c9cc03..0f6cc177b 100644 --- a/ftparchive/writer.cc +++ b/ftparchive/writer.cc @@ -634,18 +634,10 @@ bool SourcesWriter::DoPackage(string FileName) // the "db cursor" Db.Finish(); - // read stuff - char *Start = Db.Dsc.Data; - char *BlkEnd = Db.Dsc.Data + Db.Dsc.Length; - - // Add extra \n to the end, just in case (as in clearsigned they are missing) - *BlkEnd++ = '\n'; - *BlkEnd++ = '\n'; - pkgTagSection Tags; - if (Tags.Scan(Start,BlkEnd - Start) == false) + if (Tags.Scan(Db.Dsc.Data.c_str(), Db.Dsc.Data.length()) == false) return _error->Error("Could not find a record in the DSC '%s'",FileName.c_str()); - + if (Tags.Exists("Source") == false) return _error->Error("Could not find a Source entry in the DSC '%s'",FileName.c_str()); Tags.Trim(); diff --git a/test/integration/framework b/test/integration/framework index c9445065b..70ad381e9 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -780,7 +780,7 @@ buildaptarchivefromincoming() { [ -e ftparchive.conf ] || createaptftparchiveconfig [ -e dists ] || buildaptftparchivedirectorystructure msgninfo "\tGenerate Packages, Sources and Contents files… " - aptftparchive -qq generate ftparchive.conf + testsuccess aptftparchive generate ftparchive.conf cd - > /dev/null msgdone "info" generatereleasefiles diff --git a/test/integration/test-apt-ftparchive-src-cachedb b/test/integration/test-apt-ftparchive-src-cachedb index adcca6217..0ac4d558f 100755 --- a/test/integration/test-apt-ftparchive-src-cachedb +++ b/test/integration/test-apt-ftparchive-src-cachedb @@ -180,10 +180,6 @@ testequal " E: Could not find a Source entry in the DSC 'aptarchive/pool/invalid/invalid_1.0.dsc'" aptftparchive sources aptarchive/pool/invalid rm -f aptarchive/pool/invalid/invalid_1.0.dsc -dd if=/dev/zero of="aptarchive/pool/invalid/toobig_1.0.dsc" bs=1k count=129 2>/dev/null -testequal " -E: DSC file 'aptarchive/pool/invalid/toobig_1.0.dsc' is too large!" aptftparchive sources aptarchive/pool/invalid - # ensure clean works rm -f aptarchive/pool/main/* aptftparchive clean apt-ftparchive.conf -o Debug::APT::FTPArchive::Clean=1 > clean-out.txt 2>&1 -- cgit v1.2.3-70-g09d2 From b0be0e09cfbbcb033eb0b92eaf17ac31a6b9f423 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 22 Dec 2014 12:20:28 +0100 Subject: rework dpkg-wrapping in test framework We are able to run maintainer scripts if needed before, but we need to set ADMINDIR to be able to call dpkg tools like dpkg-trigger inside of them. Git-Dch: Ignore --- test/integration/framework | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'test/integration/framework') diff --git a/test/integration/framework b/test/integration/framework index f7f69f5d5..2c794d1f3 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -131,7 +131,7 @@ aptinternalsolver() { runapt "${APTINTERNALSOLVER}" "$@"; } aptdumpsolver() { runapt "${APTDUMPSOLVER}" "$@"; } dpkg() { - command dpkg --root=${TMPWORKINGDIRECTORY}/rootdir --force-not-root --force-bad-path --log=${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log "$@" + "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" "$@" } dpkgcheckbuilddeps() { command dpkg-checkbuilddeps --admindir=${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg "$@" @@ -247,15 +247,28 @@ setupenvironment() { else echo "Dir::Bin::apt-key \"${BUILDDIRECTORY}/apt-key\";" >> aptconfig.conf fi - echo "Dir::Bin::dpkg \"fakeroot\";" >> aptconfig.conf - echo "DPKG::options:: \"dpkg\";" >> aptconfig.conf - echo "DPKG::options:: \"--root=${TMPWORKINGDIRECTORY}/rootdir\";" >> aptconfig.conf - echo "DPKG::options:: \"--force-not-root\";" >> aptconfig.conf - echo "DPKG::options:: \"--force-bad-path\";" >> aptconfig.conf + + cat > "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" < rootdir/etc/apt/apt.conf.d/99dpkg + if ! command dpkg --assert-multi-arch >/dev/null 2>&1; 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 echo 'quiet::NoStatistic "true";' >> aptconfig.conf # too distracting for users, but helpful to detect changes @@ -388,22 +401,15 @@ int execvp(const char *file, char *const argv[]) { char newfile[strlen(chrootdir) + strlen(file)]; strcpy(newfile, chrootdir); strcat(newfile, file); + char const * const baseadmindir = "/var/lib/dpkg"; + char admindir[strlen(chrootdir) + strlen(baseadmindir)]; + strcpy(admindir, chrootdir); + strcat(admindir, baseadmindir); + setenv("DPKG_ADMINDIR", admindir, 1); return func_execvp(newfile, argv); } EOF testsuccess --nomsg gcc -fPIC -shared -o noopchroot.so noopchroot.c -ldl - - mkdir -p "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/" - DPKG="${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" - echo "#!/bin/sh -if [ -n \"\$LD_PRELOAD\" ]; then - export LD_PRELOAD=\"${TMPWORKINGDIRECTORY}/noopchroot.so \${LD_PRELOAD}\" -else - export LD_PRELOAD=\"${TMPWORKINGDIRECTORY}/noopchroot.so\" -fi -dpkg \"\$@\"" > $DPKG - chmod +x $DPKG - sed -ie "s|^DPKG::options:: \"dpkg\";\$|DPKG::options:: \"$DPKG\";|" aptconfig.conf } configallowinsecurerepositories() { -- cgit v1.2.3-70-g09d2 From 25b86db159fbc3c043628e285c0c1ef24dec2c6e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 10 Mar 2015 00:59:44 +0100 Subject: test exitcode as well as string equality We use test{success,failure} now all over the place in the framework, so its only consequencial to do this in the situations in which we test for a specific output as well. Git-Dch: Ignore --- test/integration/framework | 24 +++++- .../test-allow-scores-for-all-dependency-types | 22 +++--- .../test-apt-bug-718329-support-data.tar | 34 --------- test/integration/test-apt-by-hash-update | 4 +- test/integration/test-apt-cache | 32 ++++---- test/integration/test-apt-cdrom | 18 ++--- test/integration/test-apt-cli-list | 21 +++--- test/integration/test-apt-cli-search | 26 +++---- test/integration/test-apt-cli-show | 2 +- test/integration/test-apt-cli-update | 6 +- test/integration/test-apt-cli-upgrade | 6 +- test/integration/test-apt-config | 24 +++--- test/integration/test-apt-extracttemplates | 2 +- test/integration/test-apt-ftparchive-cachedb | 12 +-- .../test-apt-ftparchive-cachedb-lp1274466 | 2 +- test/integration/test-apt-ftparchive-src-cachedb | 2 +- test/integration/test-apt-get-autoremove | 6 +- test/integration/test-apt-get-build-dep | 6 +- test/integration/test-apt-get-changelog | 4 +- test/integration/test-apt-get-install-deb | 2 +- test/integration/test-apt-get-source | 18 ++--- test/integration/test-apt-get-source-arch | 16 ++-- test/integration/test-apt-get-source-multisources | 4 +- .../integration/test-apt-get-update-unauth-warning | 8 +- test/integration/test-apt-get-upgrade | 6 +- test/integration/test-apt-helper | 14 ++-- test/integration/test-apt-key | 4 +- test/integration/test-apt-key-net-update | 4 +- test/integration/test-apt-mark | 36 ++++----- test/integration/test-apt-progress-fd | 20 ++--- test/integration/test-apt-progress-fd-deb822 | 5 +- .../test-apt-translation-has-no-packages | 4 +- test/integration/test-apt-update-expected-size | 2 +- test/integration/test-apt-update-nofallback | 12 +-- test/integration/test-apt-update-rollback | 20 ++--- test/integration/test-apt-update-stale | 2 +- .../test-architecture-specification-parsing | 20 ++--- test/integration/test-authentication-basic | 2 +- .../test-bug-470115-new-and-tighten-recommends | 20 ++--- .../test-bug-507998-dist-upgrade-recommends | 2 +- .../test-bug-543966-downgrade-below-1000-pin | 10 +-- ...est-bug-549968-install-depends-of-not-installed | 2 +- .../test-bug-590041-prefer-non-virtual-packages | 8 +- ...g-590438-broken-provides-thanks-to-remove-order | 2 +- test/integration/test-bug-591882-conkeror | 4 +- .../integration/test-bug-593360-modifiers-in-names | 16 ++-- .../test-bug-596498-trusted-unsigned-repo | 12 +-- ...test-bug-598669-install-postfix-gets-exim-heavy | 2 +- test/integration/test-bug-601961-install-info | 6 +- test/integration/test-bug-602412-dequote-redirect | 2 +- .../integration/test-bug-604222-new-and-autoremove | 10 +-- .../test-bug-605394-versioned-or-groups | 2 +- test/integration/test-bug-611729-mark-as-manual | 6 +- .../test-bug-612099-multiarch-conflicts | 30 ++++---- test/integration/test-bug-612557-garbage-upgrade | 6 +- .../test-bug-613420-new-garbage-dependency | 2 +- .../test-bug-618848-always-respect-user-requests | 2 +- .../test-bug-624218-Translation-file-handling | 17 ++--- .../test-bug-632221-cross-dependency-satisfaction | 30 ++++---- ...test-bug-64141-install-dependencies-for-on-hold | 4 +- .../test-bug-657695-resolver-breaks-on-virtuals | 2 +- .../test-bug-661537-build-profiles-support | 8 +- .../test-bug-675449-essential-are-protected | 10 +-- .../test-bug-679371-apt-get-autoclean-multiarch | 2 +- .../test-bug-680041-apt-mark-holds-correctly | 20 ++--- .../test-bug-683786-build-dep-on-virtual-packages | 18 ++--- .../test-bug-686346-package-missing-architecture | 10 +-- .../test-bug-689582-100-char-long-path-names | 2 +- .../test-bug-691453-apt-cache-search-multi-pattern | 12 +-- .../test-bug-709560-set-candidate-release | 2 +- .../test-bug-712435-missing-descriptions | 18 ++--- .../test-bug-717891-abolute-uris-for-proxies | 2 +- .../test-bug-718329-support-data.tar-uncompressed | 31 ++++++++ ...st-bug-719263-print-uris-removes-authentication | 2 +- test/integration/test-bug-720597-build-dep-purge | 4 +- .../test-bug-722207-print-uris-even-if-very-quiet | 14 ++-- .../test-bug-723586-any-stripped-in-single-arch | 10 +-- test/integration/test-bug-728500-tempdir | 2 +- test/integration/test-bug-732746-preferences | 2 +- .../test-bug-735967-lib32-to-i386-unavailable | 8 +- test/integration/test-bug-738785-switch-protocol | 4 +- .../test-bug-745036-new-foreign-invalidates-cache | 2 +- .../test-bug-745046-candidate-propagation-fails | 4 +- test/integration/test-bug-753297-upgradable | 4 +- .../test-bug-758153-versioned-provides-support | 88 +++++++++++++++++++--- test/integration/test-bug-770291-reinstall | 8 +- test/integration/test-bug-multiarch-upgrade | 2 +- .../test-cachecontainer-architecture-specification | 32 ++++---- test/integration/test-compressed-indexes | 26 +++---- test/integration/test-conflicts-loop | 2 +- .../integration/test-conflicts-real-multiarch-same | 6 +- .../test-cve-2013-1051-InRelease-parsing | 8 +- test/integration/test-essential-force-loopbreak | 2 +- .../test-external-dependency-solver-protocol | 8 +- test/integration/test-handling-broken-orgroups | 14 ++-- .../test-ignore-provides-if-versioned-breaks | 18 ++--- .../test-ignore-provides-if-versioned-conflicts | 18 ++--- .../test-implicit-conflicts-real-not-virtual | 8 +- test/integration/test-kernel-helper-autoremove | 6 +- test/integration/test-multiarch-foreign | 24 +++--- .../test-ordering-ignore-not-matching-breaks | 8 +- test/integration/test-package-reinstallation | 2 +- test/integration/test-pdiff-usage | 12 +-- test/integration/test-pin-non-existent-package | 12 +-- test/integration/test-policy-pinning | 4 +- .../test-prefer-higher-priority-providers | 14 ++-- ...prefer-native-architecture-over-higher-priority | 2 +- ...prevent-markinstall-multiarch-same-versionscrew | 6 +- test/integration/test-provides-gone-with-upgrade | 2 +- test/integration/test-release-candidate-switching | 32 ++++---- test/integration/test-releasefile-verification | 30 ++++---- .../test-resolve-by-keep-new-recommends | 2 +- test/integration/test-sourceslist-trusted-options | 4 +- .../test-specific-architecture-dependencies | 30 ++++---- .../test-suggest-installed-multiarch-silbing | 16 ++-- .../test-ubuntu-bug-1098738-apt-get-source-md5sum | 20 ++--- ...u-bug-1130419-prefer-installed-ma-same-siblings | 12 +-- ...t-ubuntu-bug-1304403-obsolete-priority-standard | 4 +- test/integration/test-ubuntu-bug-614993 | 2 +- .../test-ubuntu-bug-761175-remove-purge | 4 +- ...st-ubuntu-bug-784473-InRelease-one-message-only | 2 +- .../test-ubuntu-bug-802901-multiarch-early-remove | 2 +- .../test-ubuntu-bug-806274-install-suggests | 8 +- .../test-ubuntu-bug-859188-multiarch-reinstall | 8 +- ...ubuntu-bug-985852-pre-depends-or-group-ordering | 2 +- .../test-unpack-different-version-unpacked | 14 ++-- test/integration/test-xorg-break-providers | 6 +- 127 files changed, 725 insertions(+), 645 deletions(-) delete mode 100755 test/integration/test-apt-bug-718329-support-data.tar create mode 100755 test/integration/test-bug-718329-support-data.tar-uncompressed (limited to 'test/integration/framework') diff --git a/test/integration/framework b/test/integration/framework index 5f13df1c0..ec23e41e6 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1338,7 +1338,7 @@ testwarning() { else msgtest 'Test for successful execution with warnings of' "$*" fi - local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testsuccess.output" + local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testwarning.output" if "$@" >${OUTPUT} 2>&1; then if expr match "$1" '^apt.*' >/dev/null; then if grep -q -E ' runtime error: ' "$OUTPUT"; then @@ -1388,6 +1388,26 @@ testfailure() { aptautotest 'testfailure' "$@" } +testsuccessequal() { + local CMP="$1" + shift + testsuccess "$@" + testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/testsuccess.output" "$CMP" +} +testwarningequal() { + local CMP="$1" + shift + testwarning "$@" + testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/testwarning.output" "$CMP" +} +testfailureequal() { + local CMP="$1" + shift + testfailure "$@" + testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailure.output" "$CMP" +} + + testfilestats() { msgtest "Test that file $1 has $2 $3" "$4" if [ "$4" "$3" "$(stat --format "$2" "$1")" ]; then @@ -1493,7 +1513,7 @@ aptautotest_apt_update() { aptautotest_aptget_update "$@"; } testaptautotestnodpkgwarning() { local TESTCALL="$1" while [ -n "$2" ]; do - if [ "$2" = '-s' ]; then return; fi + if expr match "$2" '^-[a-z]*s' >/dev/null 2>&1; then return; fi shift done testfailure grep '^dpkg: warning:.*ignor.*' "${TMPWORKINGDIRECTORY}/rootdir/tmp-before/${TESTCALL}.output" diff --git a/test/integration/test-allow-scores-for-all-dependency-types b/test/integration/test-allow-scores-for-all-dependency-types index e1d805ce9..56cfc9a69 100755 --- a/test/integration/test-allow-scores-for-all-dependency-types +++ b/test/integration/test-allow-scores-for-all-dependency-types @@ -42,7 +42,7 @@ setupaptarchive insertinstalledpackage 'libdb-dev' 'amd64' '5.1.7' 'Depends: libdb5.1-dev' insertinstalledpackage 'libdb5.1-dev' 'amd64' '5.1.29-7' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be REMOVED: @@ -57,7 +57,7 @@ Inst libdb-dev [5.1.7] (5.3.0 unversioned [amd64]) [] Inst libdb5.3-dev (5.3.28-3 unversioned [amd64]) Conf libdb5.3-dev (5.3.28-3 unversioned [amd64]) Conf libdb-dev (5.3.0 unversioned [amd64])' aptget dist-upgrade -st unversioned -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be REMOVED: @@ -76,25 +76,25 @@ Conf libdb-dev (5.3.0 versioned [amd64])' aptget dist-upgrade -st versioned cp -f rootdir/var/lib/dpkg/status-backup rootdir/var/lib/dpkg/status insertinstalledpackage 'foo' 'amd64' '1' insertinstalledpackage 'bar' 'amd64' '1' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages have been kept back: bar foo 0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.' aptget dist-upgrade -st unversioned -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages have been kept back: bar foo 0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.' aptget dist-upgrade -st versioned -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages have been kept back: bar foo 0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.' aptget dist-upgrade -st multipleno -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be REMOVED: @@ -106,14 +106,14 @@ Remv foo [1] Inst bar [1] (2.2 multipleyes [amd64]) Conf bar (2.2 multipleyes [amd64])' aptget dist-upgrade -st multipleyes -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: baz 0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded. Inst baz (2 unversioned [amd64]) Conf baz (2 unversioned [amd64])' aptget install baz -st unversioned -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: foo @@ -130,14 +130,14 @@ Inst baz (2 versioned [amd64]) Conf foo (2 versioned [amd64]) Conf baz (2 versioned [amd64])' aptget install baz -st versioned -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: baz 0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded. Inst baz (2 unversioned [amd64]) Conf baz (2 unversioned [amd64])' aptget install baz -st unversioned -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: foo @@ -159,7 +159,7 @@ cp -f rootdir/var/lib/dpkg/status-backup rootdir/var/lib/dpkg/status insertinstalledpackage 'gdm3' 'amd64' '1' 'Depends: libaudit0, libaudit0' insertinstalledpackage 'login' 'amd64' '1' 'Essential: yes' insertinstalledpackage 'libaudit0' 'amd64' '1' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be REMOVED: diff --git a/test/integration/test-apt-bug-718329-support-data.tar b/test/integration/test-apt-bug-718329-support-data.tar deleted file mode 100755 index 5cfb31917..000000000 --- a/test/integration/test-apt-bug-718329-support-data.tar +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh -set -e - -test_process_package_with_compression() { - COMPRESSOR="$1" - DATA_TAR="$2" - - msgtest "Testing apt-ftparchive with compression type: $COMPRESSOR" - - buildsimplenativepackage 'pkg' 'all' '1.0' '' '' 'some descr' '' '' '' "$COMPRESSOR" - testequal "debian-binary -control.tar.gz -$DATA_TAR" ar t incoming/pkg_1.0_all.deb - - testequal "Package: pkg" echo "$(aptftparchive packages incoming/|grep ^Package)" - - testequal "usr/bin/pkg-all pkg -usr/share/doc/pkg/FEATURES pkg -usr/share/doc/pkg/changelog pkg -usr/share/doc/pkg/copyright pkg" aptftparchive contents incoming/ - - rm -rf incoming/* -} - -TESTDIR=$(readlink -f $(dirname $0)) -. $TESTDIR/framework - -setupenvironment -test_process_package_with_compression "gzip" "data.tar.gz" -test_process_package_with_compression "none" "data.tar" -test_process_package_with_compression "xz" "data.tar.xz" - - - diff --git a/test/integration/test-apt-by-hash-update b/test/integration/test-apt-by-hash-update index d9d0b146f..8300c532c 100755 --- a/test/integration/test-apt-by-hash-update +++ b/test/integration/test-apt-by-hash-update @@ -29,7 +29,7 @@ mkdir -p aptarchive/dists/unstable/main/source/by-hash/SHA512 testfailure aptget upate # ensure we do not know about "foo" -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... E: Unable to locate package foo" aptget install -q -s foo @@ -37,7 +37,7 @@ E: Unable to locate package foo" aptget install -q -s foo testsuccess aptget update -o APT::Acquire::By-Hash=1 -o Acquire::Languages=none # ensure it works -testequal "Inst foo (1.0 unstable [all]) +testsuccessequal "Inst foo (1.0 unstable [all]) Conf foo (1.0 unstable [all])" aptget install -qq -s foo # add magic string to Release file ... diff --git a/test/integration/test-apt-cache b/test/integration/test-apt-cache index f47c0e08b..f3db8024f 100755 --- a/test/integration/test-apt-cache +++ b/test/integration/test-apt-cache @@ -42,45 +42,45 @@ testsuccess aptcache dump cp rootdir/tmp/testsuccess.output dump.output testsuccess test -s dump.output -testequal 'dpkg +testsuccessequal 'dpkg bar fancy foo' aptcache pkgnames -testequal 'bar' aptcache pkgnames bar -testequal 'fancy +testsuccessequal 'bar' aptcache pkgnames bar +testsuccessequal 'fancy foo' aptcache pkgnames f -testequal " foo | 1 | file:$(readlink -f .)/aptarchive/ unstable/main amd64 Packages" aptcache madison foo +testsuccessequal " foo | 1 | file:$(readlink -f .)/aptarchive/ unstable/main amd64 Packages" aptcache madison foo ### depends -testequal 'foo +testsuccessequal 'foo Depends: bar |Recommends: Recommends: Conflicts: Conflicts: ' aptcache depends foo -testequal 'foo +testsuccessequal 'foo Depends: bar Recommends: Conflicts: Conflicts: ' aptcache depends foo -o APT::Cache::ShowOnlyFirstOr=1 -testequal 'foo +testsuccessequal 'foo Depends: bar |Recommends: (>= 2) Recommends: (<< 5) Conflicts: Conflicts: ' aptcache depends foo -o APT::Cache::ShowVersion=1 -testequal 'foo +testsuccessequal 'foo Depends: bar Conflicts: Conflicts: ' aptcache depends foo --no-recommends -testequal 'foo +testsuccessequal 'foo Depends: bar' aptcache depends foo --important -testequal 'foo +testsuccessequal 'foo Conflicts: Conflicts: ' aptcache depends foo --important --no-depends --conflicts -testequal 'foo +testsuccessequal 'foo Depends: bar |Recommends: Recommends: @@ -97,7 +97,7 @@ bar ' aptcache depends foo --recurse -testequal 'foo +testsuccessequal 'foo Depends: bar bar Depends: bar @@ -107,18 +107,18 @@ bar ## rdpends -testequal 'foo +testsuccessequal 'foo Reverse Depends: bar bar' aptcache rdepends foo -testequal 'foo +testsuccessequal 'foo Reverse Depends: Replaces: bar Breaks: bar' aptcache rdepends foo -o APT::Cache::ShowDependencyType=1 -testequal 'foo +testsuccessequal 'foo Reverse Depends: Replaces: bar (<< 1) Breaks: bar (<< 1)' aptcache rdepends foo -o APT::Cache::ShowDependencyType=1 -o APT::Cache::ShowVersion=1 -testequal 'foo +testsuccessequal 'foo Reverse Depends: Breaks: bar (<< 1)' aptcache rdepends foo -o APT::Cache::ShowDependencyType=1 -o APT::Cache::ShowVersion=1 --important --breaks diff --git a/test/integration/test-apt-cdrom b/test/integration/test-apt-cdrom index 7f4b3c257..9906795ca 100755 --- a/test/integration/test-apt-cdrom +++ b/test/integration/test-apt-cdrom @@ -49,12 +49,12 @@ deb-src cdrom:[Debian APT Testdisk 0.8.15]/ stable main Unmounting CD-ROM... Repeat this process for the rest of the CDs in your set." -testequal "$CDROM_PRE +testsuccessequal "$CDROM_PRE Found 2 package indexes, 1 source indexes, 1 translation indexes and 1 signatures Found label 'Debian APT Testdisk 0.8.15' $CDROM_POST" aptcdromlog add -testequal "Using CD-ROM mount point $(readlink -f ./rootdir/media)/cdrom/ +testsuccessequal "Using CD-ROM mount point $(readlink -f ./rootdir/media)/cdrom/ Mounting CD-ROM... Stored label: Debian APT Testdisk 0.8.15 Unmounting CD-ROM..." aptcdromlog ident @@ -63,13 +63,13 @@ Unmounting CD-ROM..." aptcdromlog ident ident="$(LC_ALL=C aptcdrom ident 2>&1 )" CD_ID="$(echo "$ident" | grep "^Identifying" | head -n1 | cut -d" " -f2 | tr --delete '[]')" CD_LABEL="$(echo "$ident" | grep "^Stored label:" | head -n1 | sed "s/^[^:]*: //")" -testequal "CD::${CD_ID} \"${CD_LABEL}\"; -CD::${CD_ID}::Label \"${CD_LABEL}\";" cat rootdir/var/lib/apt/cdroms.list +testfileequal rootdir/var/lib/apt/cdroms.list "CD::${CD_ID} \"${CD_LABEL}\"; +CD::${CD_ID}::Label \"${CD_LABEL}\";" testcdromusage() { touch rootdir/var/lib/apt/extended_states - testequal 'Reading package lists... + testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following NEW packages will be installed: @@ -84,7 +84,7 @@ Conf testing (0.8.15 stable [amd64])' aptget install testing -s testsuccess aptget purge testing -y testdpkgnotinstalled testing - testequal 'Reading package lists... + testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following NEW packages will be installed: @@ -114,18 +114,18 @@ Conf testing:i386 (0.8.15 stable [i386])' aptget install testing:i386 -s testcdromusage # check Idempotence of apt-cdrom (and disabling of Translation dropping) -testequal "$CDROM_PRE +testsuccessequal "$CDROM_PRE Found 2 package indexes, 1 source indexes, 2 translation indexes and 1 signatures $CDROM_POST" aptcdromlog add -o APT::CDROM::DropTranslation=0 # take Translations from previous runs as needed -testequal "$CDROM_PRE +testsuccessequal "$CDROM_PRE Found 2 package indexes, 1 source indexes, 2 translation indexes and 1 signatures $CDROM_POST" aptcdromlog add msgtest 'Test for the german description translation of' 'testing' aptcache show testing -o Acquire::Languages=de | grep -q '^Description-de: ' && msgpass || msgfail rm -rf rootdir/var/lib/apt/lists -testequal "$CDROM_PRE +testsuccessequal "$CDROM_PRE Found 2 package indexes, 1 source indexes, 1 translation indexes and 1 signatures $CDROM_POST" aptcdromlog add msgtest 'Test for the english description translation of' 'testing' diff --git a/test/integration/test-apt-cli-list b/test/integration/test-apt-cli-list index 1487afd55..d3c44e126 100755 --- a/test/integration/test-apt-cli-list +++ b/test/integration/test-apt-cli-list @@ -27,50 +27,49 @@ setupaptarchive APTARCHIVE=$(readlink -f ./aptarchive) -testequal "Listing... +testsuccessequal "Listing... bar/now 1.0 i386 [installed,local] baz/unstable 2.0 all [upgradable from: 0.1] foo/unstable 1.0 all foobar/unstable 2.0 i386 [upgradable from: 1.0]" apt list -testequal "Listing... +testsuccessequal "Listing... foo/unstable 1.0 all foobar/unstable 2.0 i386 [upgradable from: 1.0]" apt list "foo*" -testequal "Listing... +testsuccessequal "Listing... baz/unstable 2.0 all [upgradable from: 0.1] foobar/unstable 2.0 i386 [upgradable from: 1.0]" apt list --upgradable # FIXME: hm, hm - does it make sense to have this different? shouldn't # we use "installed,upgradable" consitently? -testequal "Listing... +testsuccessequal "Listing... bar/now 1.0 i386 [installed,local] baz/now 0.1 all [installed,upgradable to: 2.0] foobar/now 1.0 i386 [installed,upgradable to: 2.0]" apt list --installed -testequal "Listing... +testsuccessequal "Listing... bar/now 1.0 i386 [installed,local] foobar/unstable 2.0 i386 [upgradable from: 1.0] foobar/now 1.0 i386 [installed,upgradable to: 2.0] " apt list bar foobar --all-versions -testequal "Listing... +testsuccessequal "Listing... bar/now 1.0 i386 [installed,local] an autogenerated dummy bar=1.0/installed " apt list bar --verbose # test for dpkg ^rc state insertinstalledpackage 'conf-only' 'i386' '1.0' '' '' 'deinstall ok config-files' -testequal "Listing... +testsuccessequal "Listing... conf-only/now 1.0 i386 [residual-config]" apt list conf-only # ensure that the users learns about multiple versions too -testequal "Listing... +testsuccessequal "Listing... baz/unstable 2.0 all [upgradable from: 0.1] N: There are 2 additional versions. Please use the '-a' switch to see them." apt list baz -o quiet=0 # test format strings for machine parseable output -apt list -qq bar baz -o APT::Cmd::use-format=true -o APT::Cmd::format="\${Package} - \${installed:Version} - \${candidate:Version}" > output.txt -testequal "bar - 1.0 - 1.0 -baz - 0.1 - 2.0" cat output.txt +testsuccessequal 'bar - 1.0 - 1.0 +baz - 0.1 - 2.0' apt list -qq bar baz -o APT::Cmd::use-format=true -o APT::Cmd::format="\${Package} - \${installed:Version} - \${candidate:Version}" diff --git a/test/integration/test-apt-cli-search b/test/integration/test-apt-cli-search index 1a28ba4da..e86661dcb 100755 --- a/test/integration/test-apt-cli-search +++ b/test/integration/test-apt-cli-search @@ -25,51 +25,51 @@ setupaptarchive APTARCHIVE=$(readlink -f ./aptarchive) -testequal 'E: You must give at least one search pattern' aptcache search -testequal 'E: You must give at least one search pattern' apt search +testfailureequal 'E: You must give at least one search pattern' aptcache search +testfailureequal 'E: You must give at least one search pattern' apt search # with OP progress -testequal "Sorting... +testsuccessequal "Sorting... Full Text Search... foo/unstable 1.0 all $DESCR " apt search xxyyzz # without op progress -testequal "foo/unstable 1.0 all +testsuccessequal "foo/unstable 1.0 all $DESCR " apt search -qq xxyyzz testempty apt search -qq --names-only xxyyzz # search name -testequal "foo/unstable 1.0 all +testsuccessequal "foo/unstable 1.0 all $DESCR " apt search -qq foo -testequal "foo/unstable 1.0 all +testsuccessequal "foo/unstable 1.0 all $DESCR " apt search -qq --names-only foo # search with multiple words is a AND search -testequal "foo/unstable 1.0 all +testsuccessequal "foo/unstable 1.0 all $DESCR " apt search -qq aabbcc xxyyzz -testequal "foo/unstable 1.0 all +testsuccessequal "foo/unstable 1.0 all $DESCR " apt search -qq 'a+b+c+' 'i*xxy{0,2}zz' # search is not case-sensitive by default -testequal "foo/unstable 1.0 all +testsuccessequal "foo/unstable 1.0 all $DESCR " apt search -qq uppercase -testequal "foo/unstable 1.0 all +testsuccessequal "foo/unstable 1.0 all $DESCR " apt search -qq 'up[pP]erc[Aa]se' # search is done in the long description -testequal "foo/unstable 1.0 all +testsuccessequal "foo/unstable 1.0 all $DESCR " apt search -qq 'long description' -testequal "foo/unstable 1.0 all +testsuccessequal "foo/unstable 1.0 all $DESCR Long description of stuff and such, with lines . @@ -77,7 +77,7 @@ testequal "foo/unstable 1.0 all " apt search --full -qq 'long description' # output is sorted and search word finds both package -testequal "bar/testing 2.0 i386 +testsuccessequal "bar/testing 2.0 i386 $DESCR2 foo/unstable 1.0 all diff --git a/test/integration/test-apt-cli-show b/test/integration/test-apt-cli-show index 930e591e0..5604620fd 100755 --- a/test/integration/test-apt-cli-show +++ b/test/integration/test-apt-cli-show @@ -24,7 +24,7 @@ APTARCHIVE=$(readlink -f ./aptarchive) # note that we do not display Description-md5 with the "apt" cmd # and also show some additional fields that are calculated -testequal "Package: foo +testsuccessequal "Package: foo Priority: optional Section: other Installed-Size: 43.0 kB diff --git a/test/integration/test-apt-cli-update b/test/integration/test-apt-cli-update index 83cc94b93..d68ab25e4 100755 --- a/test/integration/test-apt-cli-update +++ b/test/integration/test-apt-cli-update @@ -15,10 +15,10 @@ setupaptarchive --no-update APTARCHIVE=$(readlink -f ./aptarchive) -testequal 'E: The update command takes no arguments' apt update -q arguments +testfailureequal 'E: The update command takes no arguments' apt update -q arguments -testequal "1 package can be upgraded. Run 'apt list --upgradable' to see it." apt update -q +testsuccessequal "1 package can be upgraded. Run 'apt list --upgradable' to see it." apt update -q cp dpkg.status rootdir/var/lib/dpkg/status insertinstalledpackage 'foo' 'all' '2.0' -testequal 'All packages are up to date.' apt update -q +testsuccessequal 'All packages are up to date.' apt update -q diff --git a/test/integration/test-apt-cli-upgrade b/test/integration/test-apt-cli-upgrade index b6ee2270b..54f2ecd11 100755 --- a/test/integration/test-apt-cli-upgrade +++ b/test/integration/test-apt-cli-upgrade @@ -23,7 +23,7 @@ setupaptarchive APTARCHIVE=$(readlink -f ./aptarchive) # default is to allow new dependencies -testequal "The following NEW packages will be installed: +testsuccessequal "The following NEW packages will be installed: foo-new-dependency The following packages will be upgraded: foo @@ -33,7 +33,7 @@ Inst foo [1.0] (2.0 unstable [all]) Conf foo-new-dependency (2.0 unstable [all]) Conf foo (2.0 unstable [all])" apt upgrade -qq -s -# ensure -testequal "The following packages have been kept back: +# ensure the 'old' way works as well +testsuccessequal "The following packages have been kept back: foo 0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded." apt upgrade -qq -s --no-new-pkgs diff --git a/test/integration/test-apt-config b/test/integration/test-apt-config index 2f2ff9d38..2eea9a0f8 100755 --- a/test/integration/test-apt-config +++ b/test/integration/test-apt-config @@ -8,29 +8,29 @@ setupenvironment configarchitecture 'amd64' testsuccess aptconfig dump -testequal 'APT::Architecture "amd64";' aptconfig dump APT::Architecture +testsuccessequal 'APT::Architecture "amd64";' aptconfig dump APT::Architecture testempty aptconfig dump config::which::does::not::exist -testequal 'APT::Architectures ""; +testsuccessequal 'APT::Architectures ""; APT::Architectures:: "amd64";' aptconfig dump APT::Architectures -testequal 'APT::Architectures:: "amd64";' aptconfig dump --no-empty APT::Architectures -testequal 'amd64' aptconfig dump --no-empty --format='%v%n' APT::Architectures +testsuccessequal 'APT::Architectures:: "amd64";' aptconfig dump --no-empty APT::Architectures +testsuccessequal 'amd64' aptconfig dump --no-empty --format='%v%n' APT::Architectures testempty aptconfig shell -testequal 'E: Arguments not in pairs' aptconfig shell APT::Architecture +testfailureequal 'E: Arguments not in pairs' aptconfig shell APT::Architecture testempty aptconfig shell APT::Architecture ARCH # incorrect order -testequal "ARCH='amd64'" aptconfig shell ARCH APT::Architecture +testsuccessequal "ARCH='amd64'" aptconfig shell ARCH APT::Architecture ROOTDIR="$(readlink -f rootdir)" -testequal "CONFIG='apt.conf'" aptconfig shell CONFIG Dir::Etc::main -testequal "CONFIG='${ROOTDIR}/etc/apt/apt.conf'" aptconfig shell CONFIG Dir::Etc::main/f -testequal "CONFIG='etc/apt/'" aptconfig shell CONFIG Dir::Etc -testequal "CONFIG='${ROOTDIR}/etc/apt/'" aptconfig shell CONFIG Dir::Etc/ # old style -testequal "CONFIG='${ROOTDIR}/etc/apt/'" aptconfig shell CONFIG Dir::Etc/d +testsuccessequal "CONFIG='apt.conf'" aptconfig shell CONFIG Dir::Etc::main +testsuccessequal "CONFIG='${ROOTDIR}/etc/apt/apt.conf'" aptconfig shell CONFIG Dir::Etc::main/f +testsuccessequal "CONFIG='etc/apt/'" aptconfig shell CONFIG Dir::Etc +testsuccessequal "CONFIG='${ROOTDIR}/etc/apt/'" aptconfig shell CONFIG Dir::Etc/ # old style +testsuccessequal "CONFIG='${ROOTDIR}/etc/apt/'" aptconfig shell CONFIG Dir::Etc/d testempty aptconfig dump --no-empty --format='%v%n' APT::Build-Profiles export DEB_BUILD_PROFILES='nodoc stage1' -testequal 'nodoc +testsuccessequal 'nodoc stage1' aptconfig dump --no-empty --format='%v%n' APT::Build-Profiles unset DEB_BUILD_PROFILES testempty aptconfig dump --no-empty --format='%v%n' APT::Build-Profiles diff --git a/test/integration/test-apt-extracttemplates b/test/integration/test-apt-extracttemplates index 276862464..5dadc4933 100755 --- a/test/integration/test-apt-extracttemplates +++ b/test/integration/test-apt-extracttemplates @@ -35,7 +35,7 @@ Description: Some bar var OUT='rootdir/tmp/testsuccess.output' testequal "$1" cut -f1 -d' ' $OUT if [ -n "$2" ]; then - testequal '' cut -f2 -d' ' $OUT + testequal '' cut -s -f2 -d' ' $OUT else testequal '1.0' cut -f2 -d' ' $OUT fi diff --git a/test/integration/test-apt-ftparchive-cachedb b/test/integration/test-apt-ftparchive-cachedb index 866e5a469..3454ee36a 100755 --- a/test/integration/test-apt-ftparchive-cachedb +++ b/test/integration/test-apt-ftparchive-cachedb @@ -9,14 +9,14 @@ $(dpkg-deb -I ./aptarchive/pool/main/foo_1_i386.deb | grep 'Installed-Size:' | s Maintainer: Joe Sixpack Architecture: i386 Version: 1 -Filename: pool/main/foo_1_i386.deb" head -n8 ./aptarchive/dists/test/main/binary-i386/Packages +Filename: pool/main/foo_1_i386.deb" head -n8 ./aptarchive/dists/test/main/binary-i386/Packages } ensure_correct_contents_file() { - testequal "usr/bin/foo-i386 others/foo + testfileequal ./aptarchive/dists/test/Contents-i386 "usr/bin/foo-i386 others/foo usr/share/doc/foo/FEATURES others/foo usr/share/doc/foo/changelog others/foo -usr/share/doc/foo/copyright others/foo" cat ./aptarchive/dists/test/Contents-i386 +usr/share/doc/foo/copyright others/foo" } # @@ -99,8 +99,8 @@ testfileequal 'rootdir/tmp/testsuccess.output' ' Misses in Cache: 0 # and clean rm -rf aptarchive/pool/main/* -testequal "packages-main-i386.db" aptftparchive clean ftparchive.conf -q=0 +testsuccessequal "packages-main-i386.db" aptftparchive clean ftparchive.conf -q=0 testsuccess aptftparchive clean ftparchive.conf -q=0 -o Debug::APT::FTPArchive::Clean=1 cp rootdir/tmp/testsuccess.output clean-out.txt -testequal "0 Number of unique keys in the tree" grep unique clean-out.txt -testequal "packages-main-i386.db" grep packages-main-i386.db clean-out.txt +testsuccessequal "0 Number of unique keys in the tree" grep unique clean-out.txt +testsuccessequal "packages-main-i386.db" grep packages-main-i386.db clean-out.txt diff --git a/test/integration/test-apt-ftparchive-cachedb-lp1274466 b/test/integration/test-apt-ftparchive-cachedb-lp1274466 index 579ae33a6..1f86e367f 100755 --- a/test/integration/test-apt-ftparchive-cachedb-lp1274466 +++ b/test/integration/test-apt-ftparchive-cachedb-lp1274466 @@ -26,7 +26,7 @@ testsuccess grep 7da58ff901a40ecf42a730dc33198b182e9ba9ec98799fc2c2b6fabeeee40cc testfailure grep 7da58ff901a40ecf42a730dc33198b182e9ba9ec98799fc2c2b6fabeeee40cc12a0e7cadb4b66764235c56e1009dbfe8a9a566fb1eedf47a992d1fff2cc3332c old-format.dump # regression test for corruption with previous generation of cachedb -testequal "Package: foo +testsuccessequal "Package: foo Priority: optional Section: others Installed-Size: 29 diff --git a/test/integration/test-apt-ftparchive-src-cachedb b/test/integration/test-apt-ftparchive-src-cachedb index 28321e3c5..2a361ecc0 100755 --- a/test/integration/test-apt-ftparchive-src-cachedb +++ b/test/integration/test-apt-ftparchive-src-cachedb @@ -2,7 +2,7 @@ set -e assert_correct_sources_file() { - testequal "Package: bar + testsuccessequal "Package: bar Architecture: all Version: 1.0 Binary: bar diff --git a/test/integration/test-apt-get-autoremove b/test/integration/test-apt-get-autoremove index acde4b096..a0e4d3c24 100755 --- a/test/integration/test-apt-get-autoremove +++ b/test/integration/test-apt-get-autoremove @@ -20,7 +20,7 @@ testdpkgnotinstalled 'debhelper' testdpkginstalled 'po-debconf' 'unrelated' echo 'APT::NeverAutoRemove { "^debc.*nf$"; };' > rootdir/etc/apt/apt.conf.d/00autoremove -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following packages will be REMOVED: @@ -55,7 +55,7 @@ testdpkginstalled 'unrelated' 'debhelper' 'po-debconf' testsuccess aptmark auto debhelper testmarkedauto 'debhelper' 'po-debconf' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following packages will be REMOVED: @@ -65,7 +65,7 @@ Remv debhelper [8.0.0] Remv po-debconf [1.0.16]' aptget autoremove -s testsuccess aptmark hold debhelper -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget autoremove -s diff --git a/test/integration/test-apt-get-build-dep b/test/integration/test-apt-get-build-dep index 87ec6e54d..f7af5b782 100755 --- a/test/integration/test-apt-get-build-dep +++ b/test/integration/test-apt-get-build-dep @@ -32,7 +32,7 @@ Files: 1e806d32233af87437258d86b1561f57 2036 2vcard_0.5-3.diff.gz EOF -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Note, using file '2vcard_0.5-3.dsc' to get the build dependencies The following NEW packages will be installed: @@ -75,7 +75,7 @@ z2UAn1oXgTai6opwhVfkxrlmJ+iRxzuc -----END PGP SIGNATURE----- EOF -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Note, using file '2vcard_0.5-3.dsc' to get the build dependencies The following NEW packages will be installed: @@ -117,7 +117,7 @@ Description: install packages using the apt protocol - common data EOF -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Note, using directory './foo-1.0' to get the build dependencies The following NEW packages will be installed: diff --git a/test/integration/test-apt-get-changelog b/test/integration/test-apt-get-changelog index 01f2bd393..7e81c71b6 100755 --- a/test/integration/test-apt-get-changelog +++ b/test/integration/test-apt-get-changelog @@ -21,9 +21,9 @@ chmod -R -w rootdir/var/cache/apt/archives echo 'Apt::Changelogs::Server "http://localhost:8080/";' > rootdir/etc/apt/apt.conf.d/changelog.conf -testequal "'http://localhost:8080/pool/apt_1.0/changelog'" aptget changelog apt --print-uris +testsuccessequal "'http://localhost:8080/pool/apt_1.0/changelog'" aptget changelog apt --print-uris -testequal "'http://localhost:8080/pool/apt_1.0/changelog' +testsuccessequal "'http://localhost:8080/pool/apt_1.0/changelog' 'http://localhost:8080/pool/apt_1.0/changelog'" aptget changelog apt apt --print-uris cd downloaded diff --git a/test/integration/test-apt-get-install-deb b/test/integration/test-apt-get-install-deb index f2e5229cd..0f34692fe 100755 --- a/test/integration/test-apt-get-install-deb +++ b/test/integration/test-apt-get-install-deb @@ -8,7 +8,7 @@ setupenvironment configarchitecture "i386" # regression test for #754904 -testequal 'E: Unable to locate package /dev/null' aptget install -qq /dev/null +testfailureequal 'E: Unable to locate package /dev/null' aptget install -qq /dev/null # and ensure we fail for invalid debs cat > foo.deb < rootdir/etc/apt/apt.conf.d/02proxy-detect - testequal "Using proxy 'http://some-proxy' for URL 'http://www.example.com/'" apthelper auto-detect-proxy http://www.example.com + testsuccessequal "Using proxy 'http://some-proxy' for URL 'http://www.example.com/'" apthelper auto-detect-proxy http://www.example.com # https auto detect proxy script @@ -66,14 +66,14 @@ EOF chmod 755 apt-proxy-detect echo "Acquire::https::Proxy-Auto-Detect \"$(pwd)/apt-proxy-detect\";" > rootdir/etc/apt/apt.conf.d/02proxy-detect - testequal "Using proxy 'https://https-proxy' for URL 'https://ssl.example.com/'" apthelper auto-detect-proxy https://ssl.example.com + testsuccessequal "Using proxy 'https://https-proxy' for URL 'https://ssl.example.com/'" apthelper auto-detect-proxy https://ssl.example.com } test_apt_helper_download test_apt_helper_detect_proxy # test failure modes -testequal 'E: Invalid operation download' apthelper download -testequal 'E: Must specify at least one pair url/filename' apthelper download-file -testequal 'E: Must specify at least one pair url/filename' apthelper download-file http://example.org/ -testequal 'E: Need one URL as argument' apthelper auto-detect-proxy +testfailureequal 'E: Invalid operation download' apthelper download +testfailureequal 'E: Must specify at least one pair url/filename' apthelper download-file +testfailureequal 'E: Must specify at least one pair url/filename' apthelper download-file http://example.org/ +testfailureequal 'E: Need one URL as argument' apthelper auto-detect-proxy diff --git a/test/integration/test-apt-key b/test/integration/test-apt-key index b6b7b7909..989fe658c 100755 --- a/test/integration/test-apt-key +++ b/test/integration/test-apt-key @@ -17,7 +17,7 @@ testaptkeys() { if ! aptkey list | grep '^pub' > aptkey.list; then echo -n > aptkey.list fi - testequal "$1" cat ./aptkey.list + testfileequal './aptkey.list' "$1" } echo 'APT::Key::ArchiveKeyring "./keys/joesixpack.pub"; @@ -35,7 +35,7 @@ testrun() { testaptkeys 'pub 2048R/DBAC8DAE 2010-08-18' - testequal 'gpg: key DBAC8DAE: "Joe Sixpack (APT Testcases Dummy) " not changed + testsuccessequal 'gpg: key DBAC8DAE: "Joe Sixpack (APT Testcases Dummy) " not changed gpg: Total number processed: 1 gpg: unchanged: 1' aptkey --fakeroot update diff --git a/test/integration/test-apt-key-net-update b/test/integration/test-apt-key-net-update index b3c118555..2a0823bec 100755 --- a/test/integration/test-apt-key-net-update +++ b/test/integration/test-apt-key-net-update @@ -23,7 +23,7 @@ echo 'APT::Key::ArchiveKeyringURI "http://localhost:8080/ubuntu/project/test-arc echo 'APT::Key::Net-Update-Enabled "1";' >> ./aptconfig.conf # test against the "real" webserver -testequal 'Checking for new archive signing keys now +testsuccessequal 'Checking for new archive signing keys now gpg: key F68C85A3: public key "Test Automatic Archive Signing Key " imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1)' aptkey --fakeroot net-update @@ -40,7 +40,7 @@ echo 'APT::Key::ArchiveKeyringURI "http://localhost:8080/ubuntu/project/marvinpa echo 'APT::Key::Net-Update-Enabled "1";' >> ./aptconfig.conf # test against the "real" webserver -testequal "Checking for new archive signing keys now +testsuccessequal "Checking for new archive signing keys now Key 'DE66AECA9151AFA1877EC31DE8525D47528144E2' not added. It is not signed with a master key" aptkey --fakeroot net-update aptkey list | grep '^pub' > aptkey.list diff --git a/test/integration/test-apt-mark b/test/integration/test-apt-mark index 5a3ae4b2f..9b68945f9 100755 --- a/test/integration/test-apt-mark +++ b/test/integration/test-apt-mark @@ -21,20 +21,20 @@ testdpkginstalled dpkg testnoautopkg() { testempty aptmark showauto testempty aptcache showauto - testequal 'bar + testsuccessequal 'bar dpkg foo' aptmark showmanual - testequal 'bar + testsuccessequal 'bar foo' aptmark showmanual bar foo uninstalled } testfooisauto() { - testequal 'foo' aptmark showauto - testequal 'foo' aptcache showauto - testequal 'foo' aptmark showauto foo - testequal 'foo' aptcache showauto foo - testequal 'bar + testsuccessequal 'foo' aptmark showauto + testsuccessequal 'foo' aptcache showauto + testsuccessequal 'foo' aptmark showauto foo + testsuccessequal 'foo' aptcache showauto foo + testsuccessequal 'bar dpkg' aptmark showmanual - testequal 'bar' aptmark showmanual bar + testsuccessequal 'bar' aptmark showmanual bar } testmarkonpkgasauto() { testsuccess $1 $2 foo @@ -48,8 +48,8 @@ testmarkonpkgasauto() { testnoautopkg } -testequal 'E: No packages found' aptmark auto -testequal 'E: No packages found' aptmark manual +testfailureequal 'E: No packages found' aptmark auto +testfailureequal 'E: No packages found' aptmark manual testnoautopkg testmarkonpkgasauto 'aptmark' 'auto' 'manual' @@ -63,10 +63,10 @@ testnoholdpkg() { testempty aptmark showholds dpkg } testpkgonhold() { - testequal "$1" aptmark showhold - testequal "$1" aptmark showholds - testequal "$1" aptmark showhold $1 - testequal "$1" aptmark showholds $1 + testsuccessequal "$1" aptmark showhold + testsuccessequal "$1" aptmark showholds + testsuccessequal "$1" aptmark showhold $1 + testsuccessequal "$1" aptmark showholds $1 } testmarkonepkgashold() { testsuccess aptmark hold $1 @@ -79,8 +79,8 @@ testmarkonepkgashold() { testnoholdpkg } -testequal 'E: No packages found' aptmark hold -testequal 'E: No packages found' aptmark unhold +testfailureequal 'E: No packages found' aptmark hold +testfailureequal 'E: No packages found' aptmark unhold testnoholdpkg testmarkonepkgashold 'foo' @@ -97,5 +97,5 @@ fi testmarkonepkgashold 'uninstalled' testmarkonepkgashold 'uninstalled-native' -testequal 'uninstalled set on hold.' aptmark hold uninstalled -testequal 'uninstalled-native set on hold.' aptmark hold uninstalled-native +testsuccessequal 'uninstalled set on hold.' aptmark hold uninstalled +testsuccessequal 'uninstalled-native set on hold.' aptmark hold uninstalled-native diff --git a/test/integration/test-apt-progress-fd b/test/integration/test-apt-progress-fd index 90e6ef7e4..0c11aba7e 100755 --- a/test/integration/test-apt-progress-fd +++ b/test/integration/test-apt-progress-fd @@ -15,7 +15,7 @@ setupaptarchive # install native exec 3> apt-progress.log testsuccess aptget install testing=0.1 -y -o APT::Status-Fd=3 -testequal "dlstatus:1:0:Retrieving file 1 of 1 +testfileequal './apt-progress.log' 'dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:20:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Installing testing (amd64) @@ -26,12 +26,12 @@ pmstatus:dpkg-exec:50:Running dpkg pmstatus:testing:50:Configuring testing (amd64) pmstatus:testing:66.6667:Configuring testing (amd64) pmstatus:testing:83.3333:Installed testing (amd64) -pmstatus:dpkg-exec:83.3333:Running dpkg" cat apt-progress.log +pmstatus:dpkg-exec:83.3333:Running dpkg' # upgrade exec 3> apt-progress.log testsuccess aptget install testing=0.8.15 -y -o APT::Status-Fd=3 -testequal "dlstatus:1:0:Retrieving file 1 of 1 +testfileequal './apt-progress.log' 'dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:20:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Installing testing (amd64) @@ -42,12 +42,12 @@ pmstatus:dpkg-exec:50:Running dpkg pmstatus:testing:50:Configuring testing (amd64) pmstatus:testing:66.6667:Configuring testing (amd64) pmstatus:testing:83.3333:Installed testing (amd64) -pmstatus:dpkg-exec:83.3333:Running dpkg" cat apt-progress.log +pmstatus:dpkg-exec:83.3333:Running dpkg' # reinstall exec 3> apt-progress.log testsuccess aptget install testing=0.8.15 --reinstall -y -o APT::Status-Fd=3 -testequal "dlstatus:1:0:Retrieving file 1 of 1 +testfileequal './apt-progress.log' 'dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:20:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Installing testing (amd64) @@ -58,24 +58,24 @@ pmstatus:dpkg-exec:50:Running dpkg pmstatus:testing:50:Configuring testing (amd64) pmstatus:testing:66.6667:Configuring testing (amd64) pmstatus:testing:83.3333:Installed testing (amd64) -pmstatus:dpkg-exec:83.3333:Running dpkg" cat apt-progress.log +pmstatus:dpkg-exec:83.3333:Running dpkg' # and remove exec 3> apt-progress.log testsuccess aptget remove testing -y -o APT::Status-Fd=3 -testequal "pmstatus:dpkg-exec:0:Running dpkg +testfileequal './apt-progress.log' 'pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Removing testing (amd64) pmstatus:testing:25:Preparing for removal of testing (amd64) pmstatus:testing:50:Removing testing (amd64) pmstatus:testing:75:Removed testing (amd64) -pmstatus:dpkg-exec:75:Running dpkg" cat apt-progress.log +pmstatus:dpkg-exec:75:Running dpkg' # install non-native and ensure we get proper progress info exec 3> apt-progress.log testsuccess aptget install testing2:i386 -y -o APT::Status-Fd=3 # and compare -testequal "dlstatus:1:0:Retrieving file 1 of 1 +testfileequal './apt-progress.log' 'dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:20:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing2:0:Installing testing2 (i386) @@ -86,6 +86,6 @@ pmstatus:dpkg-exec:50:Running dpkg pmstatus:testing2:50:Configuring testing2 (i386) pmstatus:testing2:66.6667:Configuring testing2 (i386) pmstatus:testing2:83.3333:Installed testing2 (i386) -pmstatus:dpkg-exec:83.3333:Running dpkg" cat apt-progress.log +pmstatus:dpkg-exec:83.3333:Running dpkg' rm -f apt-progress*.log diff --git a/test/integration/test-apt-progress-fd-deb822 b/test/integration/test-apt-progress-fd-deb822 index badc985e4..ca7f14cb9 100755 --- a/test/integration/test-apt-progress-fd-deb822 +++ b/test/integration/test-apt-progress-fd-deb822 @@ -16,7 +16,7 @@ setupaptarchive exec 3> apt-progress.log testsuccess aptget install testing=0.1 -y -o APT::Status-deb822-Fd=3 -testequal "Status: progress +testfileequal './apt-progress.log' 'Status: progress Percent: 0 Message: Running dpkg @@ -62,7 +62,6 @@ Message: Installed testing (amd64) Status: progress Percent: 83.3333 Message: Running dpkg -" cat apt-progress.log - +' rm -f apt-progress*.log diff --git a/test/integration/test-apt-translation-has-no-packages b/test/integration/test-apt-translation-has-no-packages index bb2353a33..440fd30cf 100755 --- a/test/integration/test-apt-translation-has-no-packages +++ b/test/integration/test-apt-translation-has-no-packages @@ -17,7 +17,7 @@ configarchitecture "amd64" if [ ! -x ${BUILDDIRECTORY}/apt ]; then msgmsg "No ${BUILDDIRECTORY}/apt" - msgskip + msgskip exit 0 fi @@ -33,7 +33,7 @@ cp $APTARCHIVE/dists/unstable/main/binary-amd64/Packages \ # ensure that there is no Version for the package foo generated out of # the corrupted Translation-en file -testequal "foo: +testsuccessequal "foo: Installed: (none) Candidate: 1.0 Version table: diff --git a/test/integration/test-apt-update-expected-size b/test/integration/test-apt-update-expected-size index 045217a77..9711c293a 100755 --- a/test/integration/test-apt-update-expected-size +++ b/test/integration/test-apt-update-expected-size @@ -39,6 +39,6 @@ find aptarchive -name 'Packages*' | while read pkg; do done NEW_SIZE="$(stat --printf=%s aptarchive/dists/unstable/main/binary-i386/Packages)" rm -f rootdir/var/lib/apt/lists/localhost* -testequal "W: Failed to fetch http://localhost:8080/dists/unstable/main/binary-i386/Packages Writing more data than expected ($NEW_SIZE > $SIZE) +testfailureequal "W: Failed to fetch http://localhost:8080/dists/unstable/main/binary-i386/Packages Writing more data than expected ($NEW_SIZE > $SIZE) E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq diff --git a/test/integration/test-apt-update-nofallback b/test/integration/test-apt-update-nofallback index e82a976a6..71576de81 100755 --- a/test/integration/test-apt-update-nofallback +++ b/test/integration/test-apt-update-nofallback @@ -31,14 +31,14 @@ EOF assert_update_is_refused_and_last_good_state_used() { - testequal "E: The repository 'file: unstable Release.gpg' is no longer signed." aptget update -qq + testfailureequal "E: The repository 'file: unstable Release.gpg' is no longer signed." aptget update -qq assert_repo_is_intact } assert_repo_is_intact() { - testequal "foo/unstable 2.0 all" apt list -q + testsuccessequal "foo/unstable 2.0 all" apt list -q testsuccess aptget install -y -s foo testfailure aptget install -y evil testsuccess aptget source foo --print-uris @@ -97,7 +97,7 @@ test_from_inrelease_to_unsigned_with_override() testwarning aptget update --allow-insecure-repositories \ -o Acquire::AllowDowngradeToInsecureRepositories=1 # but that the individual packages are still considered untrusted - testequal "WARNING: The following packages cannot be authenticated! + testfailureequal "WARNING: The following packages cannot be authenticated! evil E: There are problems and -y was used without --force-yes" aptget install -qq -y evil } @@ -149,7 +149,7 @@ test_subvert_inrelease() # replace InRelease with something else mv $APTARCHIVE/dists/unstable/Release $APTARCHIVE/dists/unstable/InRelease - testequal "W: Failed to fetch file:${APTARCHIVE}/dists/unstable/InRelease Does not start with a cleartext signature + testfailureequal "W: Failed to fetch file:${APTARCHIVE}/dists/unstable/InRelease Does not start with a cleartext signature E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq @@ -169,7 +169,7 @@ test_inrelease_to_invalid_inrelease() sed -i 's/Codename.*/Codename: evil!'/ $APTARCHIVE/dists/unstable/InRelease inject_evil_package - testequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable InRelease: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) + testwarningequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable InRelease: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) W: Failed to fetch file:${APTARCHIVE}/dists/unstable/InRelease The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) @@ -193,7 +193,7 @@ test_release_gpg_to_invalid_release_release_gpg() echo "Some evil data" >> $APTARCHIVE/dists/unstable/Release inject_evil_package - testequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable Release.gpg: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) + testwarningequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable Release.gpg: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) W: Failed to fetch file:${APTARCHIVE}/dists/unstable/Release.gpg The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) diff --git a/test/integration/test-apt-update-rollback b/test/integration/test-apt-update-rollback index 9efc194a0..f4500b69d 100755 --- a/test/integration/test-apt-update-rollback +++ b/test/integration/test-apt-update-rollback @@ -38,7 +38,7 @@ start_with_good_inrelease() { create_fresh_archive testsuccess aptget update listcurrentlistsdirectory > lists.before - testequal "old/unstable 1.0 all" apt list -q + testsuccessequal "old/unstable 1.0 all" apt list -q } test_inrelease_to_new_inrelease() { @@ -47,7 +47,7 @@ test_inrelease_to_new_inrelease() { add_new_package '+1hour' testsuccess aptget update -o Debug::Acquire::Transaction=1 - testequal "new/unstable 1.0 all + testsuccessequal "new/unstable 1.0 all old/unstable 1.0 all" apt list -q } @@ -60,12 +60,12 @@ test_inrelease_to_broken_hash_reverts_all() { break_repository_sources_index '+1hour' # test the error condition - testequal "W: Failed to fetch file:${APTARCHIVE}/dists/unstable/main/source/Sources Hash Sum mismatch + testfailureequal "W: Failed to fetch file:${APTARCHIVE}/dists/unstable/main/source/Sources Hash Sum mismatch E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq # ensure that the Packages file is also rolled back testfileequal lists.before "$(listcurrentlistsdirectory)" - testequal "E: Unable to locate package new" aptget install new -s -qq + testfailureequal "E: Unable to locate package new" aptget install new -s -qq } test_inrelease_to_valid_release() { @@ -78,7 +78,7 @@ test_inrelease_to_valid_release() { rm $APTARCHIVE/dists/unstable/Release.gpg # update fails - testequal "E: The repository 'file: unstable Release.gpg' is no longer signed." aptget update -qq + testfailureequal "E: The repository 'file: unstable Release.gpg' is no longer signed." aptget update -qq # test that security downgrade was not successful testfileequal lists.before "$(listcurrentlistsdirectory)" @@ -101,7 +101,7 @@ test_inrelease_to_release_reverts_all() { break_repository_sources_index '+1hour' # ensure error - testequal "E: The repository 'file: unstable Release.gpg' is no longer signed." aptget update -qq # -o Debug::acquire::transaction=1 + testfailureequal "E: The repository 'file: unstable Release.gpg' is no longer signed." aptget update -qq # -o Debug::acquire::transaction=1 # ensure that the Packages file is also rolled back testfileequal lists.before "$(listcurrentlistsdirectory)" @@ -119,7 +119,7 @@ test_unauthenticated_to_invalid_inrelease() { testwarning aptget update --allow-insecure-repositories listcurrentlistsdirectory > lists.before - testequal "WARNING: The following packages cannot be authenticated! + testfailureequal "WARNING: The following packages cannot be authenticated! old E: There are problems and -y was used without --force-yes" aptget install -qq -y old @@ -127,13 +127,13 @@ E: There are problems and -y was used without --force-yes" aptget install -qq -y add_new_package '+1hour' break_repository_sources_index '+1hour' - testequal "W: Failed to fetch file:$APTARCHIVE/dists/unstable/main/source/Sources Hash Sum mismatch + testfailureequal "W: Failed to fetch file:$APTARCHIVE/dists/unstable/main/source/Sources Hash Sum mismatch E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq testfileequal lists.before "$(listcurrentlistsdirectory)" testfailure ls rootdir/var/lib/apt/lists/*_InRelease - testequal "WARNING: The following packages cannot be authenticated! + testfailureequal "WARNING: The following packages cannot be authenticated! old E: There are problems and -y was used without --force-yes" aptget install -qq -y old } @@ -144,7 +144,7 @@ test_inrelease_to_unauth_inrelease() { signreleasefiles 'Marvin Paranoid' - testequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E8525D47528144E2 + testwarningequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E8525D47528144E2 W: Failed to fetch file:$APTARCHIVE/dists/unstable/InRelease The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E8525D47528144E2 diff --git a/test/integration/test-apt-update-stale b/test/integration/test-apt-update-stale index 277aa5b09..05154641a 100755 --- a/test/integration/test-apt-update-stale +++ b/test/integration/test-apt-update-stale @@ -39,7 +39,7 @@ cp -p aptarchive/dists/unstable/main/binary-i386/saved/Packages* \ aptarchive/dists/unstable/main/binary-i386/ # ensure this raises an error -testequal "W: Failed to fetch http://localhost:8080/dists/unstable/main/binary-i386/Packages Hash Sum mismatch +testfailureequal "W: Failed to fetch http://localhost:8080/dists/unstable/main/binary-i386/Packages Hash Sum mismatch E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq testfileequal lists.before "$(listcurrentlistsdirectory)" diff --git a/test/integration/test-architecture-specification-parsing b/test/integration/test-architecture-specification-parsing index d1f6011de..f5a5b123e 100755 --- a/test/integration/test-architecture-specification-parsing +++ b/test/integration/test-architecture-specification-parsing @@ -26,7 +26,7 @@ insertinstalledpackage 'build-essential' 'all' '11.5' 'Multi-Arch: foreign' setupaptarchive -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... The following extra packages will be installed: foo @@ -38,7 +38,7 @@ Inst pkg-arch-foo (1.0 stable [${NATIVE}]) Conf foo (1.0 stable [${NATIVE}]) Conf pkg-arch-foo (1.0 stable [${NATIVE}])" aptget install pkg-arch-foo -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... The following NEW packages will be installed: pkg-arch-no-foo @@ -46,7 +46,7 @@ The following NEW packages will be installed: Inst pkg-arch-no-foo (1.0 stable [${NATIVE}]) Conf pkg-arch-no-foo (1.0 stable [${NATIVE}])" aptget install pkg-arch-no-foo -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... The following extra packages will be installed: foo @@ -58,7 +58,7 @@ Inst pkg-arch-foo-unrelated-no (1.0 stable [${NATIVE}]) Conf foo (1.0 stable [${NATIVE}]) Conf pkg-arch-foo-unrelated-no (1.0 stable [${NATIVE}])" aptget install pkg-arch-foo-unrelated-no -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... The following extra packages will be installed: foo @@ -70,7 +70,7 @@ Inst pkg-arch-foo-unrelated-no2 (1.0 stable [${NATIVE}]) Conf foo (1.0 stable [${NATIVE}]) Conf pkg-arch-foo-unrelated-no2 (1.0 stable [${NATIVE}])" aptget install pkg-arch-foo-unrelated-no2 -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... The following NEW packages will be installed: foo @@ -78,11 +78,11 @@ The following NEW packages will be installed: Inst foo (1.0 stable [${NATIVE}]) Conf foo (1.0 stable [${NATIVE}])" aptget build-dep pkg-arch-foo -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget build-dep pkg-arch-no-foo -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... The following NEW packages will be installed: foo @@ -90,7 +90,7 @@ The following NEW packages will be installed: Inst foo (1.0 stable [${NATIVE}]) Conf foo (1.0 stable [${NATIVE}])" aptget build-dep pkg-arch-foo-unrelated-no -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... The following NEW packages will be installed: foo @@ -98,13 +98,13 @@ The following NEW packages will be installed: Inst foo (1.0 stable [${NATIVE}]) Conf foo (1.0 stable [${NATIVE}])" aptget build-dep pkg-arch-foo-unrelated-no2 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget build-dep no-depends -s # this is not really testing APT - more that dpkg is in line with us configarchitecture 'amd64' 'armel' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: no-depends:armel diff --git a/test/integration/test-authentication-basic b/test/integration/test-authentication-basic index 7e74726be..3a6897b59 100755 --- a/test/integration/test-authentication-basic +++ b/test/integration/test-authentication-basic @@ -38,7 +38,7 @@ testauthsuccess() { rm -rf rootdir/var/lib/apt/lists testsuccess aptget update - testequal 'Reading package lists... + testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo diff --git a/test/integration/test-bug-470115-new-and-tighten-recommends b/test/integration/test-bug-470115-new-and-tighten-recommends index 6bc22ea7b..0970e2f23 100755 --- a/test/integration/test-bug-470115-new-and-tighten-recommends +++ b/test/integration/test-bug-470115-new-and-tighten-recommends @@ -47,7 +47,7 @@ insertpackage 'unstable' 'now-satisfiable' 'all' '2' 'Recommends: cool (>= 2)' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: cool @@ -59,7 +59,7 @@ Inst tighten-cool [1] (2 unstable [all]) Conf cool (2 unstable [all]) Conf tighten-cool (2 unstable [all])' aptget install tighten-cool -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: stuff @@ -71,7 +71,7 @@ Inst tighten-coolorstuff [1] (2 unstable [all]) Conf stuff (2 unstable [all]) Conf tighten-coolorstuff (2 unstable [all])' aptget install tighten-coolorstuff -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: cool @@ -83,7 +83,7 @@ Inst tighten-coolorstuff2 [1] (2 unstable [all]) Conf cool (2 unstable [all]) Conf tighten-coolorstuff2 (2 unstable [all])' aptget install tighten-coolorstuff2 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: cool @@ -95,7 +95,7 @@ Inst newrec-cool [1] (2 unstable [all]) Conf cool (2 unstable [all]) Conf newrec-cool (2 unstable [all])' aptget install newrec-cool -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: super @@ -109,7 +109,7 @@ Inst super (2 unstable [all]) Conf newrec-super (2 unstable [all]) Conf super (2 unstable [all])' aptget install newrec-super -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: cool @@ -121,7 +121,7 @@ Inst newrec-coolorstuff [1] (2 unstable [all]) Conf cool (2 unstable [all]) Conf newrec-coolorstuff (2 unstable [all])' aptget install newrec-coolorstuff -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: stuff @@ -133,7 +133,7 @@ Inst stuff [1] (2 unstable [all]) Conf cool-gone (2 unstable [all]) Conf stuff (2 unstable [all])' aptget install cool-gone -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: super @@ -149,7 +149,7 @@ Conf super-overtake (2 unstable [all])' aptget install super-overtake -s # if super would be in front, we would get a new here as it is new and # the first option in an or-group should be the preferred one… -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: cool @@ -163,7 +163,7 @@ Conf upgrade-over-new (2 unstable [all])' aptget install upgrade-over-new -s # the recommends wasn't used before so while we could do it now, # the user doesn't seem to need it so avoid upgrading it -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following packages will be upgraded: now-satisfiable diff --git a/test/integration/test-bug-507998-dist-upgrade-recommends b/test/integration/test-bug-507998-dist-upgrade-recommends index f3b4e04fb..70c6fb496 100755 --- a/test/integration/test-bug-507998-dist-upgrade-recommends +++ b/test/integration/test-bug-507998-dist-upgrade-recommends @@ -14,7 +14,7 @@ insertpackage 'unstable' 'wireshark' 'amd64' '1.2.1-2' 'Depends: wireshark-commo setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be upgraded: diff --git a/test/integration/test-bug-543966-downgrade-below-1000-pin b/test/integration/test-bug-543966-downgrade-below-1000-pin index f602bea95..d37539b9f 100755 --- a/test/integration/test-bug-543966-downgrade-below-1000-pin +++ b/test/integration/test-bug-543966-downgrade-below-1000-pin @@ -15,7 +15,7 @@ setupaptarchive STATUS=$(readlink -f rootdir/var/lib/dpkg/status) APTARCHIVE="$(readlink -f aptarchive)/" -testequal "base-files: +testsuccessequal "base-files: Installed: 5.0.0-1 Candidate: 5.0.0-1 Version table: @@ -28,7 +28,7 @@ echo 'Package: base-files Pin: release a=unstable Pin-Priority: 99' > rootdir/etc/apt/preferences -testequal "base-files: +testsuccessequal "base-files: Installed: 5.0.0-1 Candidate: 5.0.0-1 Package pin: 5.0.0 @@ -42,7 +42,7 @@ echo 'Package: base-files Pin: release a=unstable Pin-Priority: 100' > rootdir/etc/apt/preferences -testequal "base-files: +testsuccessequal "base-files: Installed: 5.0.0-1 Candidate: 5.0.0-1 Package pin: 5.0.0 @@ -56,7 +56,7 @@ echo 'Package: base-files Pin: release a=unstable Pin-Priority: 999' > rootdir/etc/apt/preferences -testequal "base-files: +testsuccessequal "base-files: Installed: 5.0.0-1 Candidate: 5.0.0-1 Package pin: 5.0.0 @@ -70,7 +70,7 @@ echo 'Package: base-files Pin: release a=unstable Pin-Priority: 1000' > rootdir/etc/apt/preferences -testequal "base-files: +testsuccessequal "base-files: Installed: 5.0.0-1 Candidate: 5.0.0 Package pin: 5.0.0 diff --git a/test/integration/test-bug-549968-install-depends-of-not-installed b/test/integration/test-bug-549968-install-depends-of-not-installed index 8c434b3ce..3ff4807de 100755 --- a/test/integration/test-bug-549968-install-depends-of-not-installed +++ b/test/integration/test-bug-549968-install-depends-of-not-installed @@ -14,7 +14,7 @@ setupaptarchive # We check the Markers here as the autoremove nuker will also # prevent it, but to late - its better to fail earlier -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... MarkInstall coolstuff [ i386 ] < none -> 1.0 > ( other ) FU=1 Ignore MarkInstall of extracoolstuff [ i386 ] < none -> 1.0 > ( other ) as its mode (Keep) is protected diff --git a/test/integration/test-bug-590041-prefer-non-virtual-packages b/test/integration/test-bug-590041-prefer-non-virtual-packages index 0ce4c1413..3bd7d436e 100755 --- a/test/integration/test-bug-590041-prefer-non-virtual-packages +++ b/test/integration/test-bug-590041-prefer-non-virtual-packages @@ -46,8 +46,8 @@ EOF setupaptarchive testshowvirtual libc6:i386 -testequal "$pkglibc6" aptcache show libc6:armel -testequal "$pkglibc6" aptcache show libc6 -testequal "$pkglibdb1" aptcache show libdb1:i386 +testsuccessequal "$pkglibc6" aptcache show libc6:armel +testsuccessequal "$pkglibc6" aptcache show libc6 +testsuccessequal "$pkglibdb1" aptcache show libdb1:i386 testnopackage libdb1:armel -testequal "$pkglibdb1" aptcache show libdb1 +testsuccessequal "$pkglibdb1" aptcache show libdb1 diff --git a/test/integration/test-bug-590438-broken-provides-thanks-to-remove-order b/test/integration/test-bug-590438-broken-provides-thanks-to-remove-order index 645e86d7d..37426ec11 100755 --- a/test/integration/test-bug-590438-broken-provides-thanks-to-remove-order +++ b/test/integration/test-bug-590438-broken-provides-thanks-to-remove-order @@ -29,7 +29,7 @@ predependsgawk() { echo "$pkgbasefile Pre-Depends: $1 " >> rootdir/var/lib/dpkg/status - testequal "Inst gawk (1:3.1.7.dfsg-5 localhost [i386]) + testsuccessequal "Inst gawk (1:3.1.7.dfsg-5 localhost [i386]) Conf gawk (1:3.1.7.dfsg-5 localhost [i386]) Remv mawk [1.3.3-15]" aptget install gawk mawk- -sqq -o PreDepends=$(echo "$1" | sed 's/ //g') } diff --git a/test/integration/test-bug-591882-conkeror b/test/integration/test-bug-591882-conkeror index 891ddb8b7..b71d4d5fd 100755 --- a/test/integration/test-bug-591882-conkeror +++ b/test/integration/test-bug-591882-conkeror @@ -73,5 +73,5 @@ After this operation, 36.0 MB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." # Test that the old behavior can be restored with the option -testequal "$UPGRADEFAIL" aptget dist-upgrade --trivial-only -o pkgProblemResolver::FixByInstall=0 -testequal "$UPGRADESUCCESS" aptget dist-upgrade --trivial-only #-o pkgProblemResolver::FixByInstall=0 +testfailureequal "$UPGRADEFAIL" aptget dist-upgrade --trivial-only -o pkgProblemResolver::FixByInstall=0 +testfailureequal "$UPGRADESUCCESS" aptget dist-upgrade --trivial-only #-o pkgProblemResolver::FixByInstall=0 diff --git a/test/integration/test-bug-593360-modifiers-in-names b/test/integration/test-bug-593360-modifiers-in-names index 74826cbdb..57a24683e 100755 --- a/test/integration/test-bug-593360-modifiers-in-names +++ b/test/integration/test-bug-593360-modifiers-in-names @@ -7,7 +7,7 @@ setupenvironment configarchitecture "i386" setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: g++ @@ -15,12 +15,12 @@ The following NEW packages will be installed: Inst g++ (4:4.4.5-1 localhost [i386]) Conf g++ (4:4.4.5-1 localhost [i386])' aptget install g++ -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Package 'g++' is not installed, so not removed 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove g++ -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: g++ @@ -28,7 +28,7 @@ The following NEW packages will be installed: Inst g++ (4:4.4.5-1 localhost [i386]) Conf g++ (4:4.4.5-1 localhost [i386])' aptget install g+++ -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: g++ @@ -36,7 +36,7 @@ The following NEW packages will be installed: Inst g++ (4:4.4.5-1 localhost [i386]) Conf g++ (4:4.4.5-1 localhost [i386])' aptget purge g+++ -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: apt @@ -44,7 +44,7 @@ The following NEW packages will be installed: Inst apt (0.8.8 localhost [all]) Conf apt (0.8.8 localhost [all])' aptget install apt -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: apt+ @@ -52,7 +52,7 @@ The following NEW packages will be installed: Inst apt+ (0.8.8 localhost [all]) Conf apt+ (0.8.8 localhost [all])' aptget install apt+ -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: apt+ @@ -60,7 +60,7 @@ The following NEW packages will be installed: Inst apt+ (0.8.8 localhost [all]) Conf apt+ (0.8.8 localhost [all])' aptget install apt++ -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: apt+ diff --git a/test/integration/test-bug-596498-trusted-unsigned-repo b/test/integration/test-bug-596498-trusted-unsigned-repo index 1e5e75b0e..4eb77b9a4 100755 --- a/test/integration/test-bug-596498-trusted-unsigned-repo +++ b/test/integration/test-bug-596498-trusted-unsigned-repo @@ -18,16 +18,16 @@ aptgetupdate() { PKGTEXT="$(aptget install cool --assume-no -d | head -n 7)" DEBFILE='rootdir/etc/apt/sources.list.d/apt-test-unstable-deb.list' -testequal "$PKGTEXT +testsuccessequal "$PKGTEXT Download complete and in download only mode" aptget install cool --assume-no -d -testequal "$PKGTEXT +testsuccessequal "$PKGTEXT Download complete and in download only mode" aptget install cool --assume-no -d --allow-unauthenticated sed -i -e 's#deb#deb [trusted=no]#' $DEBFILE aptgetupdate 'testsuccess' -testequal "$PKGTEXT +testfailureequal "$PKGTEXT WARNING: The following packages cannot be authenticated! cool Install these packages without verification? [y/N] N @@ -37,13 +37,13 @@ find aptarchive/ \( -name 'Release.gpg' -o -name 'InRelease' \) -delete sed -i -e 's#deb \[trusted=no\]#deb#' $DEBFILE aptgetupdate -testequal "$PKGTEXT +testfailureequal "$PKGTEXT WARNING: The following packages cannot be authenticated! cool Install these packages without verification? [y/N] N E: Some packages could not be authenticated" aptget install cool --assume-no -d -testequal "$PKGTEXT +testsuccessequal "$PKGTEXT WARNING: The following packages cannot be authenticated! cool Authentication warning overridden. @@ -52,5 +52,5 @@ Download complete and in download only mode" aptget install cool --assume-no -d sed -i -e 's#deb#deb [trusted=yes]#' $DEBFILE aptgetupdate -testequal "$PKGTEXT +testsuccessequal "$PKGTEXT Download complete and in download only mode" aptget install cool --assume-no -d diff --git a/test/integration/test-bug-598669-install-postfix-gets-exim-heavy b/test/integration/test-bug-598669-install-postfix-gets-exim-heavy index c3a77f346..2ec1d3d1c 100755 --- a/test/integration/test-bug-598669-install-postfix-gets-exim-heavy +++ b/test/integration/test-bug-598669-install-postfix-gets-exim-heavy @@ -7,7 +7,7 @@ setupenvironment configarchitecture "i386" setupaptarchive -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... The following packages will be REMOVED: exim4 exim4-daemon-light diff --git a/test/integration/test-bug-601961-install-info b/test/integration/test-bug-601961-install-info index 914910597..806d3f547 100755 --- a/test/integration/test-bug-601961-install-info +++ b/test/integration/test-bug-601961-install-info @@ -7,7 +7,7 @@ setupenvironment configarchitecture "i386" setupaptarchive -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... The following packages will be REMOVED: findutils @@ -18,7 +18,7 @@ This should NOT be done unless you know exactly what you are doing! After this operation, 1745 kB disk space will be freed. E: Trivial Only specified but this is not a trivial operation.' aptget remove findutils --trivial-only -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... The following packages will be REMOVED: install-info @@ -26,7 +26,7 @@ The following packages will be REMOVED: After this operation, 262 kB disk space will be freed. E: Trivial Only specified but this is not a trivial operation.' aptget remove install-info --trivial-only -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... The following packages will be REMOVED: essentialpkg findutils diff --git a/test/integration/test-bug-602412-dequote-redirect b/test/integration/test-bug-602412-dequote-redirect index 6393f0c27..d3573a79a 100755 --- a/test/integration/test-bug-602412-dequote-redirect +++ b/test/integration/test-bug-602412-dequote-redirect @@ -20,7 +20,7 @@ testrun() { testsuccess --nomsg aptget update # check that I-M-S header is kept in redirections - testequal "Hit $1 unstable InRelease + testsuccessequal "Hit $1 unstable InRelease Hit $1 unstable/main Sources Hit $1 unstable/main amd64 Packages Hit $1 unstable/main Translation-en diff --git a/test/integration/test-bug-604222-new-and-autoremove b/test/integration/test-bug-604222-new-and-autoremove index b29347f64..52992680b 100755 --- a/test/integration/test-bug-604222-new-and-autoremove +++ b/test/integration/test-bug-604222-new-and-autoremove @@ -11,7 +11,7 @@ touch rootdir/var/lib/apt/extended_states testsuccess aptmark markauto 'libvtk5.4' testmarkedauto 'libvtk5.4' -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Reading state information... The following package was automatically installed and is no longer required: @@ -23,7 +23,7 @@ The following NEW packages will be installed: Inst libavcodec52 (4:0.5.2-6 localhost [i386]) Conf libavcodec52 (4:0.5.2-6 localhost [i386])" aptget install libavcodec52 -s -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Reading state information... The following package was automatically installed and is no longer required: @@ -61,6 +61,6 @@ Need to get 0 B/6304 kB of archives. After this operation, 17.3 MB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation.' -testequal "$CONFLICTING" aptget install dummy-archive --trivial-only -o Debug::pkgDepCache::Marker=1 -o APT::Get::HideAutoRemove=0 -testequal "$CONFLICTING" aptget install dummy-archive --trivial-only -o Debug::pkgDepCache::Marker=1 -o APT::Get::HideAutoRemove=1 -testequal "$CONFLICTING" aptget install dummy-archive --trivial-only -o Debug::pkgDepCache::Marker=1 -o APT::Get::HideAutoRemove=small +testfailureequal "$CONFLICTING" aptget install dummy-archive --trivial-only -o Debug::pkgDepCache::Marker=1 -o APT::Get::HideAutoRemove=0 +testfailureequal "$CONFLICTING" aptget install dummy-archive --trivial-only -o Debug::pkgDepCache::Marker=1 -o APT::Get::HideAutoRemove=1 +testfailureequal "$CONFLICTING" aptget install dummy-archive --trivial-only -o Debug::pkgDepCache::Marker=1 -o APT::Get::HideAutoRemove=small diff --git a/test/integration/test-bug-605394-versioned-or-groups b/test/integration/test-bug-605394-versioned-or-groups index bb72d59e3..f938ba311 100755 --- a/test/integration/test-bug-605394-versioned-or-groups +++ b/test/integration/test-bug-605394-versioned-or-groups @@ -7,7 +7,7 @@ setupenvironment configarchitecture "i386" setupaptarchive -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be upgraded: diff --git a/test/integration/test-bug-611729-mark-as-manual b/test/integration/test-bug-611729-mark-as-manual index e3d454f97..a7bde393b 100755 --- a/test/integration/test-bug-611729-mark-as-manual +++ b/test/integration/test-bug-611729-mark-as-manual @@ -34,14 +34,14 @@ testdpkgnotinstalled a testdpkginstalled b c testmarkedauto 'b' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... b is already the newest version. 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget install b --only-upgrade testmarkedauto 'b' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... b is already the newest version. @@ -59,7 +59,7 @@ sed -i rootdir/var/log/apt/history.log -e '/^Commandline: / d' -e '/^Start-Date: testfileequal 'rootdir/var/log/apt/history.log' ' Reinstall: b:i386 (1.0)' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... b is already the newest version. diff --git a/test/integration/test-bug-612099-multiarch-conflicts b/test/integration/test-bug-612099-multiarch-conflicts index c32600037..401b521a5 100755 --- a/test/integration/test-bug-612099-multiarch-conflicts +++ b/test/integration/test-bug-612099-multiarch-conflicts @@ -17,7 +17,7 @@ setupaptarchive testsuccess aptget install libc6:i386 -t stable -y testdpkginstalled libc6:i386 -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following packages will be REMOVED: @@ -29,7 +29,7 @@ Remv libc6 [1.0] Inst libc6:amd64 (1.0 stable [amd64]) Conf libc6:amd64 (1.0 stable [amd64])' aptget install libc6:amd64 -s -t stable -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following NEW packages will be installed: @@ -38,7 +38,7 @@ The following NEW packages will be installed: Inst foobar (1.0 stable [i386]) Conf foobar (1.0 stable [i386])' aptget install foobar -st stable -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following extra packages will be installed: @@ -54,7 +54,7 @@ Inst foobar:amd64 (1.0 stable [amd64]) Conf libc6:amd64 (1.0 stable [amd64]) Conf foobar:amd64 (1.0 stable [amd64])' aptget install foobar:amd64 -st stable -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following NEW packages will be installed: @@ -67,7 +67,7 @@ Inst foobar (1.0 stable [i386]) Conf libc6 (2.0 testing [all]) Conf foobar (1.0 stable [i386])' aptget install foobar/stable libc6 -st testing -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... Calculating upgrade... @@ -84,7 +84,7 @@ testsuccess aptget purge libc6 -y testsuccess aptget install libc6:i386 -y testdpkginstalled libc6:all -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following NEW packages will be installed: @@ -93,7 +93,7 @@ The following NEW packages will be installed: Inst foobar (1.0 stable [i386]) Conf foobar (1.0 stable [i386])' aptget install foobar/stable -st testing -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following extra packages will be installed: @@ -110,7 +110,7 @@ Conf libc6:amd64 (1.0 stable [amd64]) Conf foobar:amd64 (1.0 stable [amd64])' aptget install foobar:amd64/stable -st testing -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Reading state information... Selected version '1.0' (stable [i386]) for 'libc6' @@ -133,7 +133,7 @@ setupaptarchive testsuccess aptget install libc6-same:i386 -t stable -y testdpkginstalled libc6-same:i386 -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following NEW packages will be installed: @@ -142,7 +142,7 @@ The following NEW packages will be installed: Inst foobar-same (1.0 stable [i386]) Conf foobar-same (1.0 stable [i386])' aptget install foobar-same -st stable -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following extra packages will be installed: @@ -155,7 +155,7 @@ Inst foobar-same:amd64 (1.0 stable [amd64]) Conf libc6-same:amd64 (1.0 stable [amd64]) Conf foobar-same:amd64 (1.0 stable [amd64])' aptget install foobar-same:amd64 -st stable -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following NEW packages will be installed: @@ -166,7 +166,7 @@ Conf libc6-same:amd64 (1.0 stable [amd64])' aptget install libc6-same:amd64 -s - # FIXME: We should test installing libc6-same:amd64 here, but dpkg doesn't allow it currently -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... Calculating upgrade... @@ -184,7 +184,7 @@ testsuccess aptget install libc6-same:i386 -y testdpkginstalled libc6-same:all -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Reading state information... Selected version '1.0' (stable [i386]) for 'libc6-same' @@ -194,7 +194,7 @@ The following packages will be DOWNGRADED: Inst libc6-same [2.0] (1.0 stable [i386]) Conf libc6-same (1.0 stable [i386])" aptget install libc6-same/stable -s -q=0 -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following NEW packages will be installed: @@ -203,7 +203,7 @@ The following NEW packages will be installed: Inst foobar-same (1.0 stable [i386]) Conf foobar-same (1.0 stable [i386])' aptget install foobar-same/stable -st testing -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following extra packages will be installed: diff --git a/test/integration/test-bug-612557-garbage-upgrade b/test/integration/test-bug-612557-garbage-upgrade index 910b3b149..552330d81 100755 --- a/test/integration/test-bug-612557-garbage-upgrade +++ b/test/integration/test-bug-612557-garbage-upgrade @@ -17,7 +17,7 @@ testsuccess aptmark markauto python-uno openoffice.org-common #aptmark unmarkauto openoffice.org-emailmerge testmarkedauto python-uno openoffice.org-common -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Reading state information... The following extra packages will be installed: @@ -35,7 +35,7 @@ E: Trivial Only specified but this is not a trivial operation.' aptget --trivial testsuccess aptmark markauto openoffice.org-emailmerge testmarkedauto python-uno openoffice.org-common openoffice.org-emailmerge -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Reading state information... The following extra packages will be installed: @@ -50,7 +50,7 @@ The following packages will be upgraded: After this operation, 53.2 MB disk space will be freed. E: Trivial Only specified but this is not a trivial operation.' aptget --trivial-only install python-uno -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Reading state information... The following packages will be REMOVED: diff --git a/test/integration/test-bug-613420-new-garbage-dependency b/test/integration/test-bug-613420-new-garbage-dependency index 9d9f1096a..5839f8798 100755 --- a/test/integration/test-bug-613420-new-garbage-dependency +++ b/test/integration/test-bug-613420-new-garbage-dependency @@ -18,7 +18,7 @@ touch rootdir/var/lib/apt/extended_states testsuccess aptmark markauto openoffice.org-officebean testmarkedauto openoffice.org-officebean -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Reading state information... The following packages were automatically installed and are no longer required: diff --git a/test/integration/test-bug-618848-always-respect-user-requests b/test/integration/test-bug-618848-always-respect-user-requests index 1ebadf280..a7ffee6c1 100755 --- a/test/integration/test-bug-618848-always-respect-user-requests +++ b/test/integration/test-bug-618848-always-respect-user-requests @@ -13,7 +13,7 @@ insertpackage 'unstable' 'exim4-daemon-heavy' 'all' '1.0' 'Depends: libdb4.8' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... MarkDelete libdb4.8 [ i386 ] < 1.0 > ( other ) FU=1 MarkDelete exim4-daemon-light [ i386 ] < 1.0 > ( other ) FU=0 diff --git a/test/integration/test-bug-624218-Translation-file-handling b/test/integration/test-bug-624218-Translation-file-handling index 652386892..3987abff1 100755 --- a/test/integration/test-bug-624218-Translation-file-handling +++ b/test/integration/test-bug-624218-Translation-file-handling @@ -65,29 +65,27 @@ configallowinsecurerepositories "true"; msgtest 'Download of en as forced language' 'without Index' testwarning --nomsg aptget update -o Acquire::Languages=en -cp rootdir/tmp/testsuccess.output testsuccess.output -testsuccess grep -q -e 'Translation-en ' testsuccess.output +testsuccess grep -q -e 'Translation-en ' rootdir/tmp/testwarning.output rm -rf rootdir/var/lib/apt/lists msgtest 'Download of nothing else in forced language' 'without Index' testwarning --nomsg aptget update -o Acquire::Languages=en -testfailure grep -q -e 'Translation-[^e][^n] ' rootdir/tmp/testsuccess.output +testfailure grep -q -e 'Translation-[^e][^n] ' rootdir/tmp/testwarning.output rm -rf rootdir/var/lib/apt/lists msgtest 'Download of ast_DE as forced language' 'without Index' testwarning --nomsg aptget update -o Acquire::Languages=ast_DE -cp rootdir/tmp/testsuccess.output testsuccess.output -testsuccess grep -q -e 'Translation-ast_DE$' testsuccess.output +testsuccess grep -q -e 'Translation-ast_DE$' rootdir/tmp/testwarning.output rm -rf rootdir/var/lib/apt/lists msgtest 'Download of nothing else in forced language' 'without Index' testwarning --nomsg aptget update -o Acquire::Languages=ast_DE -testfailure grep -q -e 'Translation-[^a][^s]' rootdir/tmp/testsuccess.output +testfailure grep -q -e 'Translation-[^a][^s]' rootdir/tmp/testwarning.output rm -rf rootdir/var/lib/apt/lists msgtest 'Download of nothing if none is forced' 'without Index' testwarning --nomsg aptget update -o Acquire::Languages=none -testfailure grep -q -e 'Translation' rootdir/tmp/testsuccess.output +testfailure grep -q -e 'Translation' rootdir/tmp/testwarning.output rm -rf rootdir/var/lib/apt/lists mkdir -p rootdir/var/lib/apt/lists @@ -95,8 +93,7 @@ touch rootdir/var/lib/apt/lists/localhost:8080_dists_unstable_main_i18n_Translat msgtest 'Download of builtin files' 'without Index' testwarning --nomsg aptget update -cp rootdir/tmp/testsuccess.output testsuccess.output -testsuccess grep -q -e 'Translation-ast_DE' testsuccess.output +testsuccess grep -q -e 'Translation-ast_DE' rootdir/tmp/testwarning.output rm -rf rootdir/var/lib/apt/lists mkdir -p rootdir/var/lib/apt/lists @@ -104,5 +101,5 @@ touch rootdir/var/lib/apt/lists/localhost:8080_dists_unstable_main_i18n_Translat msgtest 'Download of nothing (even builtin) if none is forced' 'without Index' testwarning --nomsg aptget update -o Acquire::Languages=none -testfailure grep -q -e 'Translation' rootdir/tmp/testsuccess.output +testfailure grep -q -e 'Translation' rootdir/tmp/testwarning.output rm -rf rootdir/var/lib/apt/lists diff --git a/test/integration/test-bug-632221-cross-dependency-satisfaction b/test/integration/test-bug-632221-cross-dependency-satisfaction index d90a103c9..563821173 100755 --- a/test/integration/test-bug-632221-cross-dependency-satisfaction +++ b/test/integration/test-bug-632221-cross-dependency-satisfaction @@ -35,17 +35,17 @@ insertsource 'unstable' 'source-specific-armel' 'armel' '1' 'Build-Depends: spec setupaptarchive -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... E: Build-Depends dependency for forbidden-none can't be satisfied because amdboot:any is not allowed on 'Multi-Arch: none' packages" aptget build-dep forbidden-none -s -a armel -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... E: Build-Depends dependency for forbidden-same can't be satisfied because libc6:any is not allowed on 'Multi-Arch: same' packages" aptget build-dep forbidden-same -s -a armel -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... E: Build-Depends dependency for forbidden-foreign can't be satisfied because doxygen:any is not allowed on 'Multi-Arch: foreign' packages" aptget build-dep forbidden-foreign -s -a armel -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libc6 specific @@ -54,7 +54,7 @@ Inst libc6 (1.0 unstable [amd64]) Inst specific (1.0 unstable [amd64]) Conf libc6 (1.0 unstable [amd64]) Conf specific (1.0 unstable [amd64])' aptget build-dep source-specific-amd64 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libc6 specific @@ -64,7 +64,7 @@ Inst specific (1.0 unstable [amd64]) Conf libc6 (1.0 unstable [amd64]) Conf specific (1.0 unstable [amd64])' aptget build-dep source-specific-amd64 -s -a armel -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libc6:armel specific:armel @@ -73,7 +73,7 @@ Inst libc6:armel (1.0 unstable [armel]) Inst specific:armel (1.0 unstable [armel]) Conf libc6:armel (1.0 unstable [armel]) Conf specific:armel (1.0 unstable [armel])' aptget build-dep source-specific-armel -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libc6:armel specific:armel @@ -83,7 +83,7 @@ Inst specific:armel (1.0 unstable [armel]) Conf libc6:armel (1.0 unstable [armel]) Conf specific:armel (1.0 unstable [armel])' aptget build-dep source-specific-armel -s -a armel -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: amdboot cool doxygen foreigner libc6 libc6-dev libfwibble-dev libfwibble1 @@ -108,7 +108,7 @@ Conf libfwibble1 (1.0 unstable [amd64]) Conf libfwibble-dev (1.0 unstable [amd64]) Conf linux-stuff (1.0 unstable [amd64])' aptget build-dep apt -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: amdboot arm-stuff:armel cool doxygen foreigner libc6 libc6:armel libc6-dev @@ -139,7 +139,7 @@ Conf libfwibble-dev:armel (1.0 unstable [armel])' aptget build-dep apt -s -a arm configarchitecture 'armel' 'amd64' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: amdboot:amd64 arm-stuff cool doxygen foreigner libc6 libc6-dev @@ -164,7 +164,7 @@ Conf libc6-dev (1.0 unstable [armel]) Conf libfwibble1 (1.0 unstable [armel]) Conf libfwibble-dev (1.0 unstable [armel])' aptget build-dep apt -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: amdboot:amd64 cool doxygen foreigner libc6:amd64 libc6 libc6-dev:amd64 @@ -198,7 +198,7 @@ configarchitecture 'amd64' 'armel' insertinstalledpackage 'cool' 'amd64' '0.5' insertinstalledpackage 'foreigner' 'armel' '0.5' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: amdboot doxygen libc6 libc6-dev libfwibble-dev libfwibble1 linux-stuff @@ -218,7 +218,7 @@ Conf libfwibble1 (1.0 unstable [amd64]) Conf libfwibble-dev (1.0 unstable [amd64]) Conf linux-stuff (1.0 unstable [amd64])' aptget build-dep apt -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: amdboot arm-stuff:armel doxygen libc6 libc6:armel libc6-dev libc6-dev:armel @@ -246,7 +246,7 @@ Conf libfwibble-dev:armel (1.0 unstable [armel])' aptget build-dep apt -s -a arm configarchitecture 'armel' 'amd64' # cool 0.5 is not M-A: allowed, so amd64 is not acceptable -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following packages will be REMOVED: cool:amd64 @@ -272,7 +272,7 @@ Conf libc6-dev (1.0 unstable [armel]) Conf libfwibble1 (1.0 unstable [armel]) Conf libfwibble-dev (1.0 unstable [armel])' aptget build-dep apt -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: amdboot:amd64 doxygen libc6:amd64 libc6 libc6-dev:amd64 libc6-dev diff --git a/test/integration/test-bug-64141-install-dependencies-for-on-hold b/test/integration/test-bug-64141-install-dependencies-for-on-hold index 9e6c223a8..ff8fa4523 100755 --- a/test/integration/test-bug-64141-install-dependencies-for-on-hold +++ b/test/integration/test-bug-64141-install-dependencies-for-on-hold @@ -19,7 +19,7 @@ insertpackage 'unstable' 'libdb4.8' 'native' '4.8.30-3' setupaptarchive -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be REMOVED: @@ -34,7 +34,7 @@ E: Trivial Only specified but this is not a trivial operation.' aptget dist-upgr testsuccess aptmark hold apt -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages have been kept back: diff --git a/test/integration/test-bug-657695-resolver-breaks-on-virtuals b/test/integration/test-bug-657695-resolver-breaks-on-virtuals index 1b92a04fe..14c90b3b9 100755 --- a/test/integration/test-bug-657695-resolver-breaks-on-virtuals +++ b/test/integration/test-bug-657695-resolver-breaks-on-virtuals @@ -16,7 +16,7 @@ insertpackage 'unstable' 'xserver-xorg-core' 'amd64' '2:1.11.3-0ubuntu9' 'Breaks setupaptarchive -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be REMOVED: diff --git a/test/integration/test-bug-661537-build-profiles-support b/test/integration/test-bug-661537-build-profiles-support index 6c850fdf9..7e7a74b03 100755 --- a/test/integration/test-bug-661537-build-profiles-support +++ b/test/integration/test-bug-661537-build-profiles-support @@ -24,7 +24,7 @@ insertsource 'unstable' 'spec-7' 'any' '1' 'Build-Depends: foo = 1)' insertinstalledpackage 'pkgz' 'none' '1' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following packages will be REMOVED: @@ -111,7 +111,7 @@ The following packages will be REMOVED: 0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded. Purg pkgy:none [1] Purg pkgx:none [1]' aptget purge pkgx -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following packages will be REMOVED: diff --git a/test/integration/test-bug-689582-100-char-long-path-names b/test/integration/test-bug-689582-100-char-long-path-names index 1b4b172b6..58ece1d5a 100755 --- a/test/integration/test-bug-689582-100-char-long-path-names +++ b/test/integration/test-bug-689582-100-char-long-path-names @@ -28,7 +28,7 @@ ar cr ../testpkg.deb debian-binary control.tar.gz data.tar.gz cd - > /dev/null -testequal '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102 testpkg +testsuccessequal '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102 testpkg 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101 testpkg 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100 testpkg 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099 testpkg diff --git a/test/integration/test-bug-691453-apt-cache-search-multi-pattern b/test/integration/test-bug-691453-apt-cache-search-multi-pattern index 0367892fc..15586b726 100755 --- a/test/integration/test-bug-691453-apt-cache-search-multi-pattern +++ b/test/integration/test-bug-691453-apt-cache-search-multi-pattern @@ -21,13 +21,13 @@ foo - tool best used with bar bar - tool best used with foo baz - alternative tool best used with foo' -testequal "$FOOBAR" aptcache search foo -testequal "$FOOBAR" aptcache search bar -testequal "$FOOBAR" aptcache search foo bar +testsuccessequal "$FOOBAR" aptcache search foo +testsuccessequal "$FOOBAR" aptcache search bar +testsuccessequal "$FOOBAR" aptcache search foo bar -testequal 'foobar - funky tool +testsuccessequal 'foobar - funky tool foo - tool best used with bar' aptcache search -n foo -testequal 'foobar - funky tool +testsuccessequal 'foobar - funky tool bar - tool best used with foo baz - alternative tool best used with foo' aptcache search -n bar -testequal 'foobar - funky tool' aptcache search -n foo bar +testsuccessequal 'foobar - funky tool' aptcache search -n foo bar diff --git a/test/integration/test-bug-709560-set-candidate-release b/test/integration/test-bug-709560-set-candidate-release index 48dc5c382..ab41d8f2a 100755 --- a/test/integration/test-bug-709560-set-candidate-release +++ b/test/integration/test-bug-709560-set-candidate-release @@ -21,7 +21,7 @@ EOF setupaptarchive -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Selected version '2.0' (experimental [all]) for 'foo' Selected version '2.1' (experimental [all]) for 'foo-dep' because of 'foo' diff --git a/test/integration/test-bug-712435-missing-descriptions b/test/integration/test-bug-712435-missing-descriptions index 7a3518745..726134326 100755 --- a/test/integration/test-bug-712435-missing-descriptions +++ b/test/integration/test-bug-712435-missing-descriptions @@ -81,43 +81,43 @@ Description-md5: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" > aptarchive/Packages setupaptarchive -testequal "Package: apt-normal +testsuccessequal "Package: apt-normal $PACKAGESTANZA $DESCRIPTION Description-md5: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " aptcache show apt-normal for variant in 'below' 'middle' 'top'; do - testequal "Package: apt-both-$variant + testsuccessequal "Package: apt-both-$variant $PACKAGESTANZA $TRANSDESCRIPTION Description-md5: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb " aptcache show apt-both-$variant done -testequal "Package: apt-trans +testsuccessequal "Package: apt-trans $PACKAGESTANZA $TRANSDESCRIPTION Description-md5: cccccccccccccccccccccccccccccccc " aptcache show apt-trans -testequal "Package: apt-md5 +testsuccessequal "Package: apt-md5 $PACKAGESTANZA Description-md5: dddddddddddddddddddddddddddddddd " aptcache show apt-md5 -testequal "Package: apt-none +testsuccessequal "Package: apt-none $PACKAGESTANZA " aptcache show apt-none -testequal "Package: apt-intermixed +testsuccessequal "Package: apt-intermixed $PACKAGESTANZA $DESCRIPTION Description-md5: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa X-Some-Flag: yes " aptcache show apt-intermixed -testequal "Package: apt-intermixed2 +testsuccessequal "Package: apt-intermixed2 $PACKAGESTANZA $TRANSDESCRIPTION Description-md5: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -126,7 +126,7 @@ X-Foo-Flag: Something with a Description X-Bar-Flag: no " aptcache show apt-intermixed2 -testequal "Package: apt-intermixed3 +testsuccessequal "Package: apt-intermixed3 $PACKAGESTANZA $TRANSDESCRIPTION Description-md5: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -152,7 +152,7 @@ Reverse Provides: ' testempty aptcache search nonexistentstring # packages without a description can't be found -testequal 'apt-normal - commandline package manager +testsuccessequal 'apt-normal - commandline package manager apt-both-below - commandline package manager apt-both-middle - commandline package manager apt-both-top - commandline package manager diff --git a/test/integration/test-bug-717891-abolute-uris-for-proxies b/test/integration/test-bug-717891-abolute-uris-for-proxies index 54a616686..ef948c2d5 100755 --- a/test/integration/test-bug-717891-abolute-uris-for-proxies +++ b/test/integration/test-bug-717891-abolute-uris-for-proxies @@ -19,7 +19,7 @@ echo 'Acquire::http::Proxy "http://localhost:8080";' > rootdir/etc/apt/apt.conf. msgtest 'Check that requests to proxies are' 'absolute uris' testsuccess --nomsg aptget update -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: unrelated diff --git a/test/integration/test-bug-718329-support-data.tar-uncompressed b/test/integration/test-bug-718329-support-data.tar-uncompressed new file mode 100755 index 000000000..d2845f768 --- /dev/null +++ b/test/integration/test-bug-718329-support-data.tar-uncompressed @@ -0,0 +1,31 @@ +#!/bin/sh +set -e + +test_process_package_with_compression() { + COMPRESSOR="$1" + DATA_TAR="$2" + + msgmsg "Testing apt-ftparchive with compression type: $COMPRESSOR" + + buildsimplenativepackage 'pkg' 'all' '1.0' '' '' 'some descr' '' '' '' "$COMPRESSOR" + testsuccessequal "debian-binary +control.tar.gz +$DATA_TAR" ar t incoming/pkg_1.0_all.deb + + testequal "Package: pkg" echo "$(aptftparchive packages incoming/|grep ^Package)" + + testsuccessequal "usr/bin/pkg-all pkg +usr/share/doc/pkg/FEATURES pkg +usr/share/doc/pkg/changelog pkg +usr/share/doc/pkg/copyright pkg" aptftparchive contents incoming/ + + rm -rf incoming/* +} + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework + +setupenvironment +test_process_package_with_compression "gzip" "data.tar.gz" +test_process_package_with_compression "none" "data.tar" +test_process_package_with_compression "xz" "data.tar.xz" diff --git a/test/integration/test-bug-719263-print-uris-removes-authentication b/test/integration/test-bug-719263-print-uris-removes-authentication index 5e674db0b..207bf4611 100755 --- a/test/integration/test-bug-719263-print-uris-removes-authentication +++ b/test/integration/test-bug-719263-print-uris-removes-authentication @@ -15,7 +15,7 @@ setupaptarchive testnoact() { cp -a rootdir/var/lib/dpkg/status rootdir/var/lib/dpkg/status-backup-noact touch rootdir/var/lib/apt/extended_states - testequal 'Reading package lists... + testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following packages will be upgraded: diff --git a/test/integration/test-bug-720597-build-dep-purge b/test/integration/test-bug-720597-build-dep-purge index 1e24ed5f1..6fa261fbd 100755 --- a/test/integration/test-bug-720597-build-dep-purge +++ b/test/integration/test-bug-720597-build-dep-purge @@ -13,7 +13,7 @@ buildsimplenativepackage 'pkgc' 'amd64' '1' 'stable' 'Build-Depends: pkgb' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following packages will be REMOVED: pkga @@ -24,7 +24,7 @@ Remv pkga [1] Inst pkgb (1 stable [amd64]) Conf pkgb (1 stable [amd64])' aptget build-dep pkgc -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following packages will be REMOVED: pkga* diff --git a/test/integration/test-bug-722207-print-uris-even-if-very-quiet b/test/integration/test-bug-722207-print-uris-even-if-very-quiet index 9a5685703..2cad929cc 100755 --- a/test/integration/test-bug-722207-print-uris-even-if-very-quiet +++ b/test/integration/test-bug-722207-print-uris-even-if-very-quiet @@ -16,15 +16,15 @@ setupaptarchive APTARCHIVE=$(readlink -f ./aptarchive) -testequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 " aptget upgrade -qq --print-uris -testequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 " aptget dist-upgrade -qq --print-uris -testequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 " aptget install apt -qq --print-uris -testequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 " aptget download apt -qq --print-uris -testequal "'file://${APTARCHIVE}/apt_2.dsc' apt_2.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e +testsuccessequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 " aptget upgrade -qq --print-uris +testsuccessequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 " aptget dist-upgrade -qq --print-uris +testsuccessequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 " aptget install apt -qq --print-uris +testsuccessequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 " aptget download apt -qq --print-uris +testsuccessequal "'file://${APTARCHIVE}/apt_2.dsc' apt_2.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e 'file://${APTARCHIVE}/apt_2.tar.gz' apt_2.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source apt -qq --print-uris -testequal "'http://packages.debian.org/changelogs/pool/main/apt/apt_2/changelog'" aptget changelog apt -qq --print-uris +testsuccessequal "'http://packages.debian.org/changelogs/pool/main/apt/apt_2/changelog'" aptget changelog apt -qq --print-uris -testequal "'file://${APTARCHIVE}/apt_2.dsc' apt_2.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e +testsuccessequal "'file://${APTARCHIVE}/apt_2.dsc' apt_2.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e 'file://${APTARCHIVE}/apt_2.tar.gz' apt_2.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e 'file://${APTARCHIVE}/apt2_1.dsc' apt2_1.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e 'file://${APTARCHIVE}/apt2_1.tar.gz' apt2_1.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source apt apt2 -qq --print-uris diff --git a/test/integration/test-bug-723586-any-stripped-in-single-arch b/test/integration/test-bug-723586-any-stripped-in-single-arch index 392b88e9f..0cf3362cf 100755 --- a/test/integration/test-bug-723586-any-stripped-in-single-arch +++ b/test/integration/test-bug-723586-any-stripped-in-single-arch @@ -41,14 +41,14 @@ The following packages have unmet dependencies: python-mips : Depends: python3:mips but it is not installable E: Unable to correct problems, you have held broken packages.' -testequal "$INSTALLLOG" aptget install python3-gnupg -s +testsuccessequal "$INSTALLLOG" aptget install python3-gnupg -s aptcache showpkg python3 > showpkg.log -testequal "$FAILLOG" aptget install python-mips -s +testfailureequal "$FAILLOG" aptget install python-mips -s # same test, but this time in a multi-arch environment configarchitecture 'amd64' 'armhf' rm rootdir/var/cache/apt/*.bin -testequal "$INSTALLLOG" aptget install python3-gnupg -s -testequal "$(sed 's#3.3.2-16 - python3#3.3.2-16 - python3:any:armhf python3#' showpkg.log)" aptcache showpkg python3 -testequal "$FAILLOG" aptget install python-mips -s +testsuccessequal "$INSTALLLOG" aptget install python3-gnupg -s +testsuccessequal "$(sed 's#3.3.2-16 - python3#3.3.2-16 - python3:any:armhf python3#' showpkg.log)" aptcache showpkg python3 +testfailureequal "$FAILLOG" aptget install python-mips -s diff --git a/test/integration/test-bug-728500-tempdir b/test/integration/test-bug-728500-tempdir index 37e5a013e..3ae94c58f 100755 --- a/test/integration/test-bug-728500-tempdir +++ b/test/integration/test-bug-728500-tempdir @@ -26,5 +26,5 @@ else fi unset TMPDIR -testequal 'coolstuff' aptcache pkgnames +testsuccessequal 'coolstuff' aptcache pkgnames testsuccess ls rootdir/var/lib/apt/lists/*InRelease diff --git a/test/integration/test-bug-732746-preferences b/test/integration/test-bug-732746-preferences index b31f98aa0..ce73f1c17 100755 --- a/test/integration/test-bug-732746-preferences +++ b/test/integration/test-bug-732746-preferences @@ -25,7 +25,7 @@ Pin-Priority: 700 #Pin: 800 EOF -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree..." aptget check msgtest "Ensure policy is applied" diff --git a/test/integration/test-bug-735967-lib32-to-i386-unavailable b/test/integration/test-bug-735967-lib32-to-i386-unavailable index 826931fe4..eb6e1a331 100755 --- a/test/integration/test-bug-735967-lib32-to-i386-unavailable +++ b/test/integration/test-bug-735967-lib32-to-i386-unavailable @@ -31,7 +31,7 @@ setupaptarchive --no-update configarchitecture 'amd64' testsuccess aptget update -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be REMOVED: @@ -43,7 +43,7 @@ Remv lib32nss-mdns [0.9-1] Inst libnss-mdns [0.9-1] (0.10-6 unstable [amd64]) Conf libnss-mdns (0.10-6 unstable [amd64])' aptget dist-upgrade -s -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable @@ -59,7 +59,7 @@ E: Unable to correct problems, you have held broken packages.' aptget install fo configarchitecture 'amd64' 'i386' testsuccess aptget update -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following NEW packages will be installed: @@ -76,7 +76,7 @@ Conf libnss-mdns (0.10-6 unstable [amd64]) Conf libnss-mdns-i386:i386 (0.10-6 unstable [i386]) Conf lib32nss-mdns (0.10-6 unstable [amd64])' aptget dist-upgrade -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: libfoo libfoo-bin:i386 diff --git a/test/integration/test-bug-738785-switch-protocol b/test/integration/test-bug-738785-switch-protocol index 0f458e099..f6336ffe3 100755 --- a/test/integration/test-bug-738785-switch-protocol +++ b/test/integration/test-bug-738785-switch-protocol @@ -23,7 +23,7 @@ msgtest 'Test that the webserver does not answer' 'http requests' downloadfile 'http://localhost:8080/pool/apt_1.0/changelog' changelog >/dev/null 2>&1 && msgfail || msgpass echo 'Apt::Changelogs::Server "http://localhost:8080/redirectme";' > rootdir/etc/apt/apt.conf.d/changelog.conf -testequal "'http://localhost:8080/redirectme/pool/apt_1.0/changelog'" aptget changelog apt --print-uris +testsuccessequal "'http://localhost:8080/redirectme/pool/apt_1.0/changelog'" aptget changelog apt --print-uris cd downloaded testsuccess aptget changelog apt -d @@ -52,7 +52,7 @@ cd - >/dev/null echo "Dir::Bin::Methods \"${COPYMETHODS}\";" >> aptconfig.conf cd downloaded -testequal "E: The method driver $(readlink -f './../')/rootdir/usr/lib/apt/methods/https could not be found. +testfailureequal "E: The method driver $(readlink -f './../')/rootdir/usr/lib/apt/methods/https could not be found. N: Is the package apt-transport-https installed?" aptget download apt -q=0 testfailure test -e apt_1.0_all.deb cd - >/dev/null diff --git a/test/integration/test-bug-745036-new-foreign-invalidates-cache b/test/integration/test-bug-745036-new-foreign-invalidates-cache index 2b7ee06ad..bfa0f817c 100755 --- a/test/integration/test-bug-745036-new-foreign-invalidates-cache +++ b/test/integration/test-bug-745036-new-foreign-invalidates-cache @@ -14,7 +14,7 @@ setupaptarchive testsuccess aptget check -s configarchitecture 'amd64' 'i386' -testequal 'E: The package cache was built for different architectures: amd64 vs amd64,i386' aptget check -s -o pkgCacheFile::Generate=false +testfailureequal 'E: The package cache was built for different architectures: amd64 vs amd64,i386' aptget check -s -o pkgCacheFile::Generate=false testsuccess aptget check -s diff --git a/test/integration/test-bug-745046-candidate-propagation-fails b/test/integration/test-bug-745046-candidate-propagation-fails index e4aa67a72..f54e1872e 100755 --- a/test/integration/test-bug-745046-candidate-propagation-fails +++ b/test/integration/test-bug-745046-candidate-propagation-fails @@ -14,7 +14,7 @@ insertpackage 'experimental' 'gedit' 'amd64' '2' 'Depends: common (>= 2)' setupaptarchive -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2' (experimental [amd64]) for 'gedit' Some packages could not be installed. This may mean that you have @@ -29,7 +29,7 @@ E: Unable to correct problems, you have held broken packages." aptget install ge insertinstalledpackage 'common' 'amd64' '2' -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Selected version '2' (experimental [amd64]) for 'gedit' The following packages will be upgraded: diff --git a/test/integration/test-bug-753297-upgradable b/test/integration/test-bug-753297-upgradable index 01395a095..53bf3361b 100755 --- a/test/integration/test-bug-753297-upgradable +++ b/test/integration/test-bug-753297-upgradable @@ -25,9 +25,9 @@ insertpackage 'testing' 'bar' 'all' '2' setupaptarchive -testequal "Listing... +testsuccessequal "Listing... bar/testing 2 all [upgradable from: 1]" apt list --upgradable -testequal "Listing... +testsuccessequal "Listing... bar/testing 2 all [upgradable from: 1] foo/testing,now 1 all [installed]" apt list diff --git a/test/integration/test-bug-758153-versioned-provides-support b/test/integration/test-bug-758153-versioned-provides-support index 21f9123c9..30bc921c3 100755 --- a/test/integration/test-bug-758153-versioned-provides-support +++ b/test/integration/test-bug-758153-versioned-provides-support @@ -24,9 +24,15 @@ insertpackage 'experimental' 'foreign-webserver' 'i386' '4' 'Multi-Arch: foreign Provides: httpd (= 4)' insertpackage 'experimental' 'cool-webapp' 'all' '4' 'Depends: httpd (>= 4)' +# arch-qualified provides, see #777071 +insertpackage 'unstable' 'foo' 'all' '1' 'Provides: bar:i386' +insertpackage 'unstable' 'baz' 'i386,amd64' '1' 'Depends: bar' +insertpackage 'experimental' 'baz' 'i386,amd64' '2' 'Depends: bar:i386' +insertpackage 'experimental' 'baz-broken' 'i386' '2' 'Depends: bar:amd64' + setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be upgraded: @@ -37,7 +43,7 @@ Inst webapp [1] (2 unstable [all]) Conf webserver (2 unstable [amd64]) Conf webapp (2 unstable [all])' aptget dist-upgrade -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following packages will be upgraded: webapp webserver @@ -47,7 +53,7 @@ Inst webapp [1] (2 unstable [all]) Conf webserver (2 unstable [amd64]) Conf webapp (2 unstable [all])' aptget install webapp webserver -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following packages will be upgraded: webapp webserver @@ -57,7 +63,7 @@ Inst webapp [1] (3 experimental [all]) Conf webserver (2 unstable [amd64]) Conf webapp (3 experimental [all])' aptget install webapp=3 webserver -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following packages will be upgraded: webapp webserver @@ -67,7 +73,7 @@ Inst webapp [1] (2 unstable [all]) Conf webserver (3 experimental [amd64]) Conf webapp (2 unstable [all])' aptget install webapp webserver=3 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foreign-webserver:i386 @@ -79,7 +85,7 @@ Inst webapp [1] (2 unstable [all]) Conf foreign-webserver:i386 (2 unstable [i386]) Conf webapp (2 unstable [all])' aptget install webapp foreign-webserver:i386 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foreign-webserver:i386 @@ -91,7 +97,7 @@ Inst webapp [1] (3 experimental [all]) Conf foreign-webserver:i386 (2 unstable [i386]) Conf webapp (3 experimental [all])' aptget install webapp=3 foreign-webserver:i386 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foreign-webserver:i386 @@ -103,7 +109,7 @@ Inst webapp [1] (2 unstable [all]) Conf foreign-webserver:i386 (4 experimental [i386]) Conf webapp (2 unstable [all])' aptget install webapp foreign-webserver:i386=4 -s -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable @@ -115,7 +121,7 @@ The following packages have unmet dependencies: cool-webapp : Depends: httpd (>= 4) E: Unable to correct problems, you have held broken packages.' aptget install cool-webapp -s -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable @@ -127,7 +133,7 @@ The following packages have unmet dependencies: cool-webapp : Depends: httpd (>= 4) E: Unable to correct problems, you have held broken packages.' aptget install cool-webapp foreign-webserver:i386 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: cool-webapp foreign-webserver:i386 @@ -136,3 +142,65 @@ Inst foreign-webserver:i386 (4 experimental [i386]) Inst cool-webapp (4 experimental [all]) Conf foreign-webserver:i386 (4 experimental [i386]) Conf cool-webapp (4 experimental [all])' aptget install cool-webapp foreign-webserver:i386=4 -s + +testsuccessequal 'Reading package lists... +Building dependency tree... +The following extra packages will be installed: + foo +The following NEW packages will be installed: + baz:i386 foo +0 upgraded, 2 newly installed, 0 to remove and 2 not upgraded. +Inst foo (1 unstable [all]) +Inst baz:i386 (1 unstable [i386]) +Conf foo (1 unstable [all]) +Conf baz:i386 (1 unstable [i386])' aptget install baz:i386 -s + +testfailureequal 'Reading package lists... +Building dependency tree... +Some packages could not be installed. This may mean that you have +requested an impossible situation or if you are using the unstable +distribution that some required packages have not yet been created +or been moved out of Incoming. +The following information may help to resolve the situation: + +The following packages have unmet dependencies: + baz : Depends: bar but it is not installable +E: Unable to correct problems, you have held broken packages.' aptget install baz:amd64 -s + +testsuccessequal "Reading package lists... +Building dependency tree... +Selected version '2' (experimental [amd64]) for 'baz' +The following extra packages will be installed: + foo +The following NEW packages will be installed: + baz foo +0 upgraded, 2 newly installed, 0 to remove and 2 not upgraded. +Inst foo (1 unstable [all]) +Inst baz (2 experimental [amd64]) +Conf foo (1 unstable [all]) +Conf baz (2 experimental [amd64])" aptget install baz/experimental -s -q=0 + +testsuccessequal "Reading package lists... +Building dependency tree... +Selected version '2' (experimental [i386]) for 'baz:i386' +The following extra packages will be installed: + foo +The following NEW packages will be installed: + baz:i386 foo +0 upgraded, 2 newly installed, 0 to remove and 2 not upgraded. +Inst foo (1 unstable [all]) +Inst baz:i386 (2 experimental [i386]) +Conf foo (1 unstable [all]) +Conf baz:i386 (2 experimental [i386])" aptget install baz:i386/experimental -s -q=0 + +testfailureequal 'Reading package lists... +Building dependency tree... +Some packages could not be installed. This may mean that you have +requested an impossible situation or if you are using the unstable +distribution that some required packages have not yet been created +or been moved out of Incoming. +The following information may help to resolve the situation: + +The following packages have unmet dependencies: + baz-broken:i386 : Depends: bar but it is not installable +E: Unable to correct problems, you have held broken packages.' aptget install baz-broken -s diff --git a/test/integration/test-bug-770291-reinstall b/test/integration/test-bug-770291-reinstall index ea1f57ede..a5b2aff07 100755 --- a/test/integration/test-bug-770291-reinstall +++ b/test/integration/test-bug-770291-reinstall @@ -39,7 +39,7 @@ Essential: yes' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... 0 upgraded, 0 newly installed, 2 reinstalled, 0 to remove and 0 not upgraded. Inst systemd [215-5+b1] (215-5+b1 unstable [i386]) @@ -47,7 +47,7 @@ Conf systemd (215-5+b1 unstable [i386]) Inst systemd-sysv [215-5+b1] (215-5+b1 unstable [i386]) Conf systemd-sysv (215-5+b1 unstable [i386])' aptget install --reinstall systemd systemd-sysv -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... 0 upgraded, 0 newly installed, 2 reinstalled, 0 to remove and 0 not upgraded. Inst dependsA [1] (1 unstable [i386]) @@ -68,7 +68,7 @@ testequal "E: Could not configure 'predependsdependsB:i386'. " tail -n1 rootdir/ msgmsg 'While we are at it, lets try these loops without reinstall as well' cp dpkg.status rootdir/var/lib/dpkg/status -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: systemd systemd-sysv @@ -78,7 +78,7 @@ Conf systemd (215-5+b1 unstable [i386]) Inst systemd-sysv (215-5+b1 unstable [i386]) Conf systemd-sysv (215-5+b1 unstable [i386])' aptget install systemd systemd-sysv -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: dependsA dependsB diff --git a/test/integration/test-bug-multiarch-upgrade b/test/integration/test-bug-multiarch-upgrade index c29e1f903..56071f184 100755 --- a/test/integration/test-bug-multiarch-upgrade +++ b/test/integration/test-bug-multiarch-upgrade @@ -16,7 +16,7 @@ insertpackage 'unstable' 'libcups2' 'i386' '2' 'Multi-Arch: same' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: libcups2 diff --git a/test/integration/test-cachecontainer-architecture-specification b/test/integration/test-cachecontainer-architecture-specification index 47abfb5b0..e5625e811 100755 --- a/test/integration/test-cachecontainer-architecture-specification +++ b/test/integration/test-cachecontainer-architecture-specification @@ -12,31 +12,31 @@ insertpackage 'unstable' 'foo' 'all' '1' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libsame 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Inst libsame (1 unstable [amd64]) Conf libsame (1 unstable [amd64])' aptget -s install libsame -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libsame:armel 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Inst libsame:armel (1 unstable [armel]) Conf libsame:armel (1 unstable [armel])' aptget -s install libsame:armel -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... E: Unable to locate package libsame' aptget -s install libsame:armhf -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libsame 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Inst libsame (1 unstable [amd64]) Conf libsame (1 unstable [amd64])' aptget -s install libsame:amd64 -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libsame libsame:armel @@ -45,7 +45,7 @@ Inst libsame (1 unstable [amd64]) Inst libsame:armel (1 unstable [armel]) Conf libsame (1 unstable [amd64]) Conf libsame:armel (1 unstable [armel])' aptget -s install libsame:armel libsame:amd64 -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libsame libsame:armel @@ -54,14 +54,14 @@ Inst libsame (1 unstable [amd64]) Inst libsame:armel (1 unstable [armel]) Conf libsame (1 unstable [amd64]) Conf libsame:armel (1 unstable [armel])' aptget -s install libsame:* -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libsame 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Inst libsame (1 unstable [amd64]) Conf libsame (1 unstable [amd64])' aptget -s install libsame:any -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libsame libsame:armel @@ -70,14 +70,14 @@ Inst libsame (1 unstable [amd64]) Inst libsame:armel (1 unstable [armel]) Conf libsame (1 unstable [amd64]) Conf libsame:armel (1 unstable [armel])' aptget -s install libsame:a* -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libsame 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Inst libsame (1 unstable [amd64]) Conf libsame (1 unstable [amd64])' aptget -s install libsame:linux-any -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libsame libsame:armel @@ -86,35 +86,35 @@ Inst libsame (1 unstable [amd64]) Inst libsame:armel (1 unstable [armel]) Conf libsame (1 unstable [amd64]) Conf libsame:armel (1 unstable [armel])' aptget -s install libsame:linux-* -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... E: Unable to locate package libsame' aptget -s install libsame:windows-any -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... E: Unable to locate package foo' aptget -s install foo:armel -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Inst foo (1 unstable [all]) Conf foo (1 unstable [all])' aptget -s install foo -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Inst foo (1 unstable [all]) Conf foo (1 unstable [all])' aptget -s install foo:all -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Inst foo (1 unstable [all]) Conf foo (1 unstable [all])' aptget -s install foo:amd64 -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo diff --git a/test/integration/test-compressed-indexes b/test/integration/test-compressed-indexes index 92e7c0e84..5b966754c 100755 --- a/test/integration/test-compressed-indexes +++ b/test/integration/test-compressed-indexes @@ -63,7 +63,7 @@ testrun() { msgtest '\tdeb file is present'; testsuccess --nomsg test -f testpkg_1.0_i386.deb rm testpkg_1.0_i386.deb cd - >/dev/null - testequal 'Reading package lists... + testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: testpkg @@ -71,14 +71,14 @@ The following NEW packages will be installed: Inst testpkg (1.0 unstable [i386]) Conf testpkg (1.0 unstable [i386])' aptget install testpkg -s rm -f rootdir/var/cache/apt/pkgcache.bin rootdir/var/cache/apt/srcpkgcache.bin - testequal "$GOODSHOW" aptcache show testpkg - testequal "$GOODSHOW" aptcache show testpkg + testsuccessequal "$GOODSHOW" aptcache show testpkg + testsuccessequal "$GOODSHOW" aptcache show testpkg rm -f rootdir/var/cache/apt/pkgcache.bin rootdir/var/cache/apt/srcpkgcache.bin - testequal "$GOODPOLICY" aptcache policy testpkg - testequal "$GOODPOLICY" aptcache policy testpkg + testsuccessequal "$GOODPOLICY" aptcache policy testpkg + testsuccessequal "$GOODPOLICY" aptcache policy testpkg rm -f rootdir/var/cache/apt/pkgcache.bin rootdir/var/cache/apt/srcpkgcache.bin - testequal "$GOODSHOWSRC" aptcache showsrc testpkg - testequal "$GOODSHOWSRC" aptcache showsrc testpkg + testsuccessequal "$GOODSHOWSRC" aptcache showsrc testpkg + testsuccessequal "$GOODSHOWSRC" aptcache showsrc testpkg aptget clean msgtest 'Check if the source is aptgetable' cd downloaded @@ -87,7 +87,7 @@ Conf testpkg (1.0 unstable [i386])' aptget install testpkg -s testsuccess test -d testpkg-1.0 rm -rf testpkg-1.0* cd - >/dev/null - testequal "$(aptcache show testpkg -o Acquire::Languages=none) + testsuccessequal "$(aptcache show testpkg -o Acquire::Languages=none) " aptcache dumpavail } @@ -134,14 +134,14 @@ testsuccess aptget update GOODSHOW="$(aptcache show testpkg) " test $(echo "$GOODSHOW" | grep -e '^Package: testpkg' -e '^Version: 1.0' -e '^Architecture: i386' | wc -l) -eq 3 || msgdie 'show is broken' -testequal "$GOODSHOW" aptcache show testpkg +testsuccessequal "$GOODSHOW" aptcache show testpkg GOODSHOWSRC="$(aptcache showsrc testpkg) " test $(echo "$GOODSHOWSRC" | grep -e '^Package: testpkg' -e '^Format: 3.0 (native)' -e '^Files:' -e '^Checksums-Sha256:' | wc -l) -eq 4 || msgdie 'showsrc is broken' -testequal "$GOODSHOWSRC" aptcache showsrc testpkg +testsuccessequal "$GOODSHOWSRC" aptcache showsrc testpkg GOODPOLICY="$(aptcache policy testpkg)" test $(echo "$GOODPOLICY" | grep -e '^testpkg:' -e '^ Candidate:' -e '^ Installed: (none)' -e '500 file:/' | wc -l) -eq 4 || msgdie 'policy is broken' -testequal "$GOODPOLICY" aptcache policy testpkg +testsuccessequal "$GOODPOLICY" aptcache policy testpkg for COMPRESSOR in 'gzip' 'bzip2' 'lzma' 'xz'; do testovermethod 'file' $COMPRESSOR; done @@ -150,7 +150,7 @@ rm -rf rootdir/var/lib/apt/lists testsuccess aptget update GOODPOLICY="$(aptcache policy testpkg)" test $(echo "$GOODPOLICY" | grep -e '^testpkg:' -e '^ Candidate:' -e '^ Installed: (none)' -e '500 http://' | wc -l) -eq 4 || msgdie 'policy is broken' -testequal "$GOODPOLICY" aptcache policy testpkg +testsuccessequal "$GOODPOLICY" aptcache policy testpkg for COMPRESSOR in 'gzip' 'bzip2' 'lzma' 'xz'; do testovermethod 'http' $COMPRESSOR; done @@ -159,6 +159,6 @@ rm -rf rootdir/var/lib/apt/lists testsuccess aptcdrom add &1 | grep -E -q '(Writing more data than expected|Hash Sum mismatch)' > /dev/null && msgpass || msgfail # ensure there is no package -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... E: Unable to locate package bad-mitm' aptget install bad-mitm -s # and verify that its not picked up -testequal 'N: Unable to locate package bad-mitm' aptcache policy bad-mitm -q=0 +testsuccessequal 'N: Unable to locate package bad-mitm' aptcache policy bad-mitm -q=0 # and that the right one is used -testequal "good-pkg: +testsuccessequal "good-pkg: Installed: (none) Candidate: 1.0 Version table: diff --git a/test/integration/test-essential-force-loopbreak b/test/integration/test-essential-force-loopbreak index 1493430d8..50c682d43 100755 --- a/test/integration/test-essential-force-loopbreak +++ b/test/integration/test-essential-force-loopbreak @@ -25,7 +25,7 @@ cp -a rootdir/var/lib/dpkg/status dpkg.status.backup testforcebreak() { cp -a dpkg.status.backup rootdir/var/lib/dpkg/status rm -f rootdir/var/lib/apt/extended_states - testequal "Reading package lists... + testfailureequal "Reading package lists... Building dependency tree... The following extra packages will be installed: sysvinit diff --git a/test/integration/test-external-dependency-solver-protocol b/test/integration/test-external-dependency-solver-protocol index fd68578c5..3b9b38c39 100755 --- a/test/integration/test-external-dependency-solver-protocol +++ b/test/integration/test-external-dependency-solver-protocol @@ -25,7 +25,7 @@ insertpackage 'experimental' 'coolstuff' 'i386,amd64' '3' 'Depends: cool, stuff' setupaptarchive rm -f /tmp/dump.edsp -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Execute external solver... The solver encountered an error of type: ERR_JUST_DUMPING @@ -38,7 +38,7 @@ testsuccess test -s /tmp/dump.edsp rm -f /tmp/dump.edsp #FIXME: this should be unstable, but we don't support pinning yet -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Execute external solver... The following NEW packages will be installed: @@ -47,7 +47,7 @@ The following NEW packages will be installed: Inst coolstuff (3 experimental [amd64]) Conf coolstuff (3 experimental [amd64])' aptget install --solver apt coolstuff -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Execute external solver... The following packages will be REMOVED: @@ -86,7 +86,7 @@ rm -f /tmp/dump.edsp testfailure aptget install --solver apt awesomecoolstuff:i386 -s testsuccess aptinternalsolver scenario -testequal 'Package: stuff +testsuccessequal 'Package: stuff Source: stuff Architecture: all Version: 1 diff --git a/test/integration/test-handling-broken-orgroups b/test/integration/test-handling-broken-orgroups index 20b314074..149f05fa9 100755 --- a/test/integration/test-handling-broken-orgroups +++ b/test/integration/test-handling-broken-orgroups @@ -23,7 +23,7 @@ Provides: stuff-abi-2' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: cool @@ -35,7 +35,7 @@ Inst coolstuff (1.0-1 unstable [all]) Conf cool (1.0-1 unstable [all]) Conf coolstuff (1.0-1 unstable [all])' aptget install coolstuff -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: stuff @@ -47,7 +47,7 @@ Inst coolstuff2 (1.0-1 unstable [all]) Conf stuff (1.0-1 unstable [all]) Conf coolstuff2 (1.0-1 unstable [all])' aptget install coolstuff2 -s -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable @@ -60,7 +60,7 @@ The following packages have unmet dependencies: stuff2 but it is not installable E: Unable to correct problems, you have held broken packages.' aptget install coolstuff-broken -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Recommended packages: cool2 stuff2 @@ -70,7 +70,7 @@ The following NEW packages will be installed: Inst coolstuff-brokenrec (1.0-1 unstable [all]) Conf coolstuff-brokenrec (1.0-1 unstable [all])' aptget install coolstuff-brokenrec -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: stuff @@ -82,7 +82,7 @@ Inst coolstuff-conflict (1.0-1 unstable [all]) Conf stuff (1.0-1 unstable [all]) Conf coolstuff-conflict (1.0-1 unstable [all])' aptget install coolstuff-conflict -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: extrastuff @@ -94,7 +94,7 @@ Inst coolstuff-provided (1.0-1 unstable [all]) Conf extrastuff (1.0-1 unstable [all]) Conf coolstuff-provided (1.0-1 unstable [all])' aptget install coolstuff-provided -s -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable diff --git a/test/integration/test-ignore-provides-if-versioned-breaks b/test/integration/test-ignore-provides-if-versioned-breaks index 745f7d206..20424b942 100755 --- a/test/integration/test-ignore-provides-if-versioned-breaks +++ b/test/integration/test-ignore-provides-if-versioned-breaks @@ -33,7 +33,7 @@ insertpackage 'unstable' 'foo-same-breaker-none' 'i386' '1.0' 'Breaks: foo-same' setupaptarchive -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable @@ -45,7 +45,7 @@ The following packages have unmet dependencies: foo-breaker-none : Breaks: foo E: Unable to correct problems, you have held broken packages.' aptget install foo-provider foo-breaker-none -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo-breaker-2 foo-provider @@ -55,7 +55,7 @@ Inst foo-provider (1.0 unstable [i386]) Conf foo-breaker-2 (1.0 unstable [i386]) Conf foo-provider (1.0 unstable [i386])' aptget install foo-provider foo-breaker-2 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: foo @@ -71,7 +71,7 @@ Conf foo (4.0 unstable [i386]) Conf foo-breaker-3 (1.0 unstable [i386]) Conf foo-provider (1.0 unstable [i386])' aptget install foo-provider foo-breaker-3 -s -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable @@ -83,7 +83,7 @@ The following packages have unmet dependencies: foo-foreign-breaker-none : Breaks: foo-foreign E: Unable to correct problems, you have held broken packages.' aptget install foo-foreign-provider foo-foreign-breaker-none -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo-foreign-breaker-2 foo-foreign-provider @@ -93,7 +93,7 @@ Inst foo-foreign-provider (1.0 unstable [i386]) Conf foo-foreign-breaker-2 (1.0 unstable [i386]) Conf foo-foreign-provider (1.0 unstable [i386])' aptget install foo-foreign-provider foo-foreign-breaker-2 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: foo-foreign:amd64 @@ -109,7 +109,7 @@ Conf foo-foreign:amd64 (4.0 unstable [amd64]) Conf foo-foreign-breaker-3 (1.0 unstable [i386]) Conf foo-foreign-provider (1.0 unstable [i386])' aptget install foo-foreign-provider foo-foreign-breaker-3 -s -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable @@ -121,7 +121,7 @@ The following packages have unmet dependencies: foo-same-breaker-none : Breaks: foo-same E: Unable to correct problems, you have held broken packages.' aptget install foo-same-provider foo-same-breaker-none -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo-same-breaker-2 foo-same-provider @@ -131,7 +131,7 @@ Inst foo-same-provider (1.0 unstable [i386]) Conf foo-same-breaker-2 (1.0 unstable [i386]) Conf foo-same-provider (1.0 unstable [i386])' aptget install foo-same-provider foo-same-breaker-2 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: foo-same:amd64 foo-same diff --git a/test/integration/test-ignore-provides-if-versioned-conflicts b/test/integration/test-ignore-provides-if-versioned-conflicts index a07252768..a781d8e44 100755 --- a/test/integration/test-ignore-provides-if-versioned-conflicts +++ b/test/integration/test-ignore-provides-if-versioned-conflicts @@ -33,7 +33,7 @@ insertpackage 'unstable' 'foo-same-breaker-none' 'i386' '1.0' 'Conflicts: foo-sa setupaptarchive -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable @@ -45,7 +45,7 @@ The following packages have unmet dependencies: foo-breaker-none : Conflicts: foo E: Unable to correct problems, you have held broken packages.' aptget install foo-provider foo-breaker-none -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo-breaker-2 foo-provider @@ -55,7 +55,7 @@ Inst foo-provider (1.0 unstable [i386]) Conf foo-breaker-2 (1.0 unstable [i386]) Conf foo-provider (1.0 unstable [i386])' aptget install foo-provider foo-breaker-2 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: foo @@ -71,7 +71,7 @@ Conf foo (4.0 unstable [i386]) Conf foo-breaker-3 (1.0 unstable [i386]) Conf foo-provider (1.0 unstable [i386])' aptget install foo-provider foo-breaker-3 -s -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable @@ -83,7 +83,7 @@ The following packages have unmet dependencies: foo-foreign-breaker-none : Conflicts: foo-foreign E: Unable to correct problems, you have held broken packages.' aptget install foo-foreign-provider foo-foreign-breaker-none -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo-foreign-breaker-2 foo-foreign-provider @@ -93,7 +93,7 @@ Inst foo-foreign-provider (1.0 unstable [i386]) Conf foo-foreign-breaker-2 (1.0 unstable [i386]) Conf foo-foreign-provider (1.0 unstable [i386])' aptget install foo-foreign-provider foo-foreign-breaker-2 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: foo-foreign:amd64 @@ -109,7 +109,7 @@ Conf foo-foreign:amd64 (4.0 unstable [amd64]) Conf foo-foreign-breaker-3 (1.0 unstable [i386]) Conf foo-foreign-provider (1.0 unstable [i386])' aptget install foo-foreign-provider foo-foreign-breaker-3 -s -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable @@ -121,7 +121,7 @@ The following packages have unmet dependencies: foo-same-breaker-none : Conflicts: foo-same E: Unable to correct problems, you have held broken packages.' aptget install foo-same-provider foo-same-breaker-none -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo-same-breaker-2 foo-same-provider @@ -131,7 +131,7 @@ Inst foo-same-provider (1.0 unstable [i386]) Conf foo-same-breaker-2 (1.0 unstable [i386]) Conf foo-same-provider (1.0 unstable [i386])' aptget install foo-same-provider foo-same-breaker-2 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: foo-same:amd64 foo-same diff --git a/test/integration/test-implicit-conflicts-real-not-virtual b/test/integration/test-implicit-conflicts-real-not-virtual index c9fca4edf..7c1365bdd 100755 --- a/test/integration/test-implicit-conflicts-real-not-virtual +++ b/test/integration/test-implicit-conflicts-real-not-virtual @@ -17,7 +17,7 @@ insertinstalledpackage 'wireless-crda' 'amd64' '1.14' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: crda @@ -25,7 +25,7 @@ The following NEW packages will be installed: Inst crda (1.1.1-1ubuntu4m unstable-m [amd64]) Conf crda (1.1.1-1ubuntu4m unstable-m [amd64])' aptget install crda -s -t unstable-m -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: crda @@ -33,7 +33,7 @@ The following NEW packages will be installed: Inst crda (1.1.1-1ubuntu4p unstable-p [amd64]) Conf crda (1.1.1-1ubuntu4p unstable-p [amd64])' aptget install crda -s -t unstable-p -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: crda @@ -47,7 +47,7 @@ Conflicts: wireless-crda (<< 1.15) Replaces: wireless-crda ( << 1.15) Multi-arch: foreign' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: wireless-crda diff --git a/test/integration/test-kernel-helper-autoremove b/test/integration/test-kernel-helper-autoremove index 1524ed4c7..c2fc37ee7 100755 --- a/test/integration/test-kernel-helper-autoremove +++ b/test/integration/test-kernel-helper-autoremove @@ -55,7 +55,7 @@ testprotected() { grep -q "^\\^linux-image-$(uname -r | sed -e 's#\.#\\\\.#g')\\\$\$" protected.list && msgpass || catfail } -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Reading state information... The following packages will be REMOVED: @@ -73,7 +73,7 @@ testprotected msgtest 'Check kernel autoremoval protection list does not include' 'old kernel' grep -q '^\^linux-image-1\\\.0\\\.0-2-generic\$$' protected.list && catfail || msgpass -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following packages will be REMOVED: @@ -85,7 +85,7 @@ Remv linux-image-1.0.0-2-generic [1.0.0-2]' aptget autoremove -s testprotected 1.0.0-2-generic msgtest 'Check kernel autoremoval protection list includes' 'installed kernel' grep -q '^\^linux-image-1\\\.0\\\.0-2-generic\$$' protected.list && msgpass || catfail -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Reading state information... The following packages will be REMOVED: diff --git a/test/integration/test-multiarch-foreign b/test/integration/test-multiarch-foreign index 332466d96..490abb873 100755 --- a/test/integration/test-multiarch-foreign +++ b/test/integration/test-multiarch-foreign @@ -15,7 +15,7 @@ Multi-Arch: foreign' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: foo @@ -27,7 +27,7 @@ Inst cool-foo:i386 (1.0 unstable [i386]) Conf foo (1.0 unstable [amd64]) Conf cool-foo:i386 (1.0 unstable [i386])' aptget install cool-foo:i386 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: foo @@ -39,7 +39,7 @@ Inst cool-foo (1.0 unstable [amd64]) Conf foo (1.0 unstable [amd64]) Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: cool-foo foo @@ -49,7 +49,7 @@ Inst cool-foo (1.0 unstable [amd64]) Conf foo (1.0 unstable [amd64]) Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 foo:amd64 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: cool-foo foo:i386 @@ -59,7 +59,7 @@ Inst cool-foo (1.0 unstable [amd64]) Conf foo:i386 (1.0 unstable [i386]) Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 foo:i386 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: cool-foo foo:armel @@ -73,7 +73,7 @@ Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 foo:armel -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: bar @@ -85,7 +85,7 @@ Inst cool-bar:i386 (1.0 unstable [i386]) Conf bar (1.0 unstable [amd64]) Conf cool-bar:i386 (1.0 unstable [i386])' aptget install cool-bar:i386 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: bar @@ -97,7 +97,7 @@ Inst cool-bar (1.0 unstable [amd64]) Conf bar (1.0 unstable [amd64]) Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: bar cool-bar @@ -107,7 +107,7 @@ Inst cool-bar (1.0 unstable [amd64]) Conf bar (1.0 unstable [amd64]) Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 bar:amd64 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: bar:i386 cool-bar @@ -117,7 +117,7 @@ Inst cool-bar (1.0 unstable [amd64]) Conf bar:i386 (1.0 unstable [i386]) Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 bar:i386 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: bar:armel cool-bar @@ -127,7 +127,7 @@ Inst cool-bar (1.0 unstable [amd64]) Conf bar:armel (1.0 unstable [armel]) Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 bar:armel -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Note, selecting 'bar' instead of 'bar-provider' The following NEW packages will be installed: @@ -138,7 +138,7 @@ Inst cool-bar (1.0 unstable [amd64]) Conf bar (1.0 unstable [amd64]) Conf cool-bar (1.0 unstable [amd64])" aptget install cool-bar bar-provider -s -q=0 -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Note, selecting 'bar:i386' instead of 'bar-provider:i386' The following NEW packages will be installed: diff --git a/test/integration/test-ordering-ignore-not-matching-breaks b/test/integration/test-ordering-ignore-not-matching-breaks index c9fca4edf..7c1365bdd 100755 --- a/test/integration/test-ordering-ignore-not-matching-breaks +++ b/test/integration/test-ordering-ignore-not-matching-breaks @@ -17,7 +17,7 @@ insertinstalledpackage 'wireless-crda' 'amd64' '1.14' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: crda @@ -25,7 +25,7 @@ The following NEW packages will be installed: Inst crda (1.1.1-1ubuntu4m unstable-m [amd64]) Conf crda (1.1.1-1ubuntu4m unstable-m [amd64])' aptget install crda -s -t unstable-m -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: crda @@ -33,7 +33,7 @@ The following NEW packages will be installed: Inst crda (1.1.1-1ubuntu4p unstable-p [amd64]) Conf crda (1.1.1-1ubuntu4p unstable-p [amd64])' aptget install crda -s -t unstable-p -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: crda @@ -47,7 +47,7 @@ Conflicts: wireless-crda (<< 1.15) Replaces: wireless-crda ( << 1.15) Multi-arch: foreign' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: wireless-crda diff --git a/test/integration/test-package-reinstallation b/test/integration/test-package-reinstallation index b4f2061ec..f0412f98d 100755 --- a/test/integration/test-package-reinstallation +++ b/test/integration/test-package-reinstallation @@ -14,7 +14,7 @@ insertinstalledpackage 'apt' 'i386' '0.8.15' 'Depends: libc6' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... 0 upgraded, 0 newly installed, 2 reinstalled, 0 to remove and 0 not upgraded. Inst libc-bin [2.13-8] (2.13-8 unstable [i386]) diff --git a/test/integration/test-pdiff-usage b/test/integration/test-pdiff-usage index d773dcd66..4de07f1ad 100755 --- a/test/integration/test-pdiff-usage +++ b/test/integration/test-pdiff-usage @@ -60,7 +60,7 @@ testrun() { testsuccess aptget update "$@" cp -a rootdir/var/lib/apt/lists rootdir/var/lib/apt/lists-bak testnopackage newstuff - testequal "$(cat ${PKGFILE}) + testsuccessequal "$(cat ${PKGFILE}) " aptcache show apt oldstuff msgmsg "Testcase: apply with one patch: $*" @@ -90,13 +90,13 @@ SHA256-Patches: find aptarchive -name 'Packages*' -type f -delete wasmergeused "$@" testnopackage oldstuff - testequal "$(cat ${PKGFILE}-new) + testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt newstuff msgmsg "Testcase: index is already up-to-date: $*" find rootdir/var/lib/apt/lists -name '*diff_Index' -type f -delete testsuccess aptget update "$@" - testequal "$(cat ${PKGFILE}-new) + testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt newstuff msgmsg "Testcase: apply with two patches: $*" @@ -146,7 +146,7 @@ SHA256-Patches: cp -a rootdir/var/lib/apt/lists-bak rootdir/var/lib/apt/lists wasmergeused "$@" testnopackage oldstuff - testequal "$(cat Packages-future) + testsuccessequal "$(cat Packages-future) " aptcache show apt newstuff futurestuff msgmsg "Testcase: patch applying fails, but successful fallback: $*" @@ -178,7 +178,7 @@ SHA256-Patches: signreleasefiles testsuccess aptget update "$@" testnopackage oldstuff - testequal "$(cat ${PKGFILE}-new) + testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt newstuff msgmsg "Testcase: pdiff patch bigger than index itself: $*" @@ -212,7 +212,7 @@ SHA256-Patches: cp -f rootdir/tmp/testsuccess.output rootdir/tmp/aptgetupdate.output testsuccess grep 'bytes (Limit is' rootdir/tmp/aptgetupdate.output testnopackage oldstuff - testequal "$(cat ${PKGFILE}-new) + testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt newstuff } echo 'Debug::pkgAcquire::Diffs "true"; diff --git a/test/integration/test-pin-non-existent-package b/test/integration/test-pin-non-existent-package index c567e5285..5c839283f 100755 --- a/test/integration/test-pin-non-existent-package +++ b/test/integration/test-pin-non-existent-package @@ -23,8 +23,8 @@ testcandidate() { } testcandidate rapt '0.8.15' -testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0 -testequal 'Reading package lists... +testsuccessequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0 +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade --trivial-only @@ -34,8 +34,8 @@ Pin: release a=unstable Pin-Priority: -1' > rootdir/etc/apt/preferences testcandidate rapt '(none)' -testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0 -testequal 'Reading package lists... +testsuccessequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0 +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade --trivial-only @@ -53,9 +53,9 @@ Pin: release a=unstable Pin-Priority: 1000' >> rootdir/etc/apt/preferences testcandidate rapt '(none)' -testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0 +testsuccessequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0 -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade --trivial-only diff --git a/test/integration/test-policy-pinning b/test/integration/test-policy-pinning index c08a2f103..15bf300ac 100755 --- a/test/integration/test-policy-pinning +++ b/test/integration/test-policy-pinning @@ -17,7 +17,7 @@ testequalpolicy() { local SP="$1" local AP="$2" shift 2 - testequal "Package files: + testsuccessequal "Package files: $(echo "$SP" | awk '{ printf("%3s\n",$0) }') ${STATUS} release a=now $(echo "$AP" | awk '{ printf("%3s\n",$0) }') file:${APTARCHIVE}/ Packages @@ -126,7 +126,7 @@ testequalpolicycoolstuff() { shift fi shift 6 - testequal "coolstuff: + testsuccessequal "coolstuff: Installed: $INSTALLED Candidate: $CANDIDATE ${PINVERSION}Version table:${BPO2ARCHIVE} diff --git a/test/integration/test-prefer-higher-priority-providers b/test/integration/test-prefer-higher-priority-providers index 64b901dd0..85a302fb1 100755 --- a/test/integration/test-prefer-higher-priority-providers +++ b/test/integration/test-prefer-higher-priority-providers @@ -13,7 +13,7 @@ insertpackage 'unstable' 'awesome' 'all' '1' 'Depends: stuff' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: foo @@ -25,7 +25,7 @@ Inst awesome (1 unstable [all]) Conf foo (1 unstable [all]) Conf awesome (1 unstable [all])' aptget install awesome -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: awesome foo @@ -35,7 +35,7 @@ Inst awesome (1 unstable [all]) Conf foo (1 unstable [all]) Conf awesome (1 unstable [all])' aptget install awesome foo -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Package 'bar' is not installed, so not removed Package 'baz' is not installed, so not removed @@ -49,7 +49,7 @@ Inst awesome (1 unstable [all]) Conf foo (1 unstable [all]) Conf awesome (1 unstable [all])" aptget install awesome bar- baz- -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Package 'foo' is not installed, so not removed The following extra packages will be installed: @@ -62,7 +62,7 @@ Inst awesome (1 unstable [all]) Conf bar (1 unstable [all]) Conf awesome (1 unstable [all])" aptget install awesome foo- -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Package 'foo' is not installed, so not removed Package 'baz' is not installed, so not removed @@ -76,7 +76,7 @@ Inst awesome (1 unstable [all]) Conf bar (1 unstable [all]) Conf awesome (1 unstable [all])" aptget install awesome foo- baz- -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Package 'foo' is not installed, so not removed Package 'bar' is not installed, so not removed @@ -90,7 +90,7 @@ Inst awesome (1 unstable [all]) Conf baz (1 unstable [all]) Conf awesome (1 unstable [all])" aptget install awesome foo- bar- -s -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Package 'foo' is not installed, so not removed Package 'bar' is not installed, so not removed diff --git a/test/integration/test-prefer-native-architecture-over-higher-priority b/test/integration/test-prefer-native-architecture-over-higher-priority index 2e5696376..7e4f8f34b 100755 --- a/test/integration/test-prefer-native-architecture-over-higher-priority +++ b/test/integration/test-prefer-native-architecture-over-higher-priority @@ -12,7 +12,7 @@ insertpackage 'unstable' 'autoconf' 'all' '1' 'Depends: m4' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: m4 diff --git a/test/integration/test-prevent-markinstall-multiarch-same-versionscrew b/test/integration/test-prevent-markinstall-multiarch-same-versionscrew index db97687ce..5f67c0191 100755 --- a/test/integration/test-prevent-markinstall-multiarch-same-versionscrew +++ b/test/integration/test-prevent-markinstall-multiarch-same-versionscrew @@ -38,7 +38,7 @@ insertpackage 'unstable' 'libsame3' 'i386,amd64' '3' 'Multi-Arch: same' insertpackage 'unstable' 'depender3' 'all' '3' 'Depends: libsame3 (= 3)' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be REMOVED: @@ -69,7 +69,7 @@ insertinstalledpackage 'libsame2' 'i386' '1' 'Multi-Arch: same' insertinstalledpackage 'libsame3' 'i386' '1' 'Multi-Arch: same' # the error message isn't great, but better than nothing, right? -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable @@ -81,7 +81,7 @@ The following packages have unmet dependencies: depender2 : Depends: libsame2 (= 2) but it is not going to be installed E: Unable to correct problems, you have held broken packages.' aptget install depender2 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: libsame3:i386 libsame3 diff --git a/test/integration/test-provides-gone-with-upgrade b/test/integration/test-provides-gone-with-upgrade index 3b4bc2d04..61d34fa57 100755 --- a/test/integration/test-provides-gone-with-upgrade +++ b/test/integration/test-provides-gone-with-upgrade @@ -13,7 +13,7 @@ Replaces: apt (<< 0.8.15)' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following NEW packages will be installed: diff --git a/test/integration/test-release-candidate-switching b/test/integration/test-release-candidate-switching index 0970cb935..a1a6a6142 100755 --- a/test/integration/test-release-candidate-switching +++ b/test/integration/test-release-candidate-switching @@ -54,7 +54,7 @@ insertpackage 'experimental' 'uninstallablepkg' 'all' '1.0' 'Depends: libmtp8 (> setupaptarchive -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... The following extra packages will be installed: amarok-common (2.3.1-1+sid) @@ -73,7 +73,7 @@ The following NEW packages will be installed: After this operation, 258 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." aptget install amarok --trivial-only -V -q=0 -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... The following extra packages will be installed: amarok-common (2.3.2-2+exp) @@ -92,7 +92,7 @@ The following NEW packages will be installed: After this operation, 258 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." aptget install amarok -t experimental --trivial-only -V -q=0 -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok' Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok' @@ -114,7 +114,7 @@ The following NEW packages will be installed: After this operation, 258 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." aptget install amarok/experimental --trivial-only -V -q=0 -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-null' Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-null' @@ -137,7 +137,7 @@ After this operation, 258 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." aptget install amarok-null/experimental --trivial-only -V -q=0 # do not select the same version multiple times -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok' Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok' @@ -165,7 +165,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a # in theory, the second line is wrong, but printing the right version is too much of a hassle # (we have to check if later in the Changed list is another change and if so use this version # instead of the current candidate) - and it wouldn't be (really) useful anyway… -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2.3.2-2+exp' (experimental2 [i386]) for 'amarok-less' Selected version '5:4.6.0+exp' (experimental [i386]) for 'phonon-backend-xine' because of 'amarok-less' @@ -192,7 +192,7 @@ After this operation, 301 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." aptget install amarok-less/experimental2 amarok-higher/experimental --trivial-only -V -q=0 # phonon-backend-null can't be used directly, but as it provides it is still fine… -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-null2' Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-null2' @@ -215,7 +215,7 @@ After this operation, 258 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." aptget install amarok-null2/experimental --trivial-only -V -q=0 # if an or-group satisfier is already found, do not set others -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-xine' Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-xine' @@ -239,7 +239,7 @@ After this operation, 258 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." aptget install amarok-xine/experimental --trivial-only -V -q=0 # … but proceed testing if the first doesn't work out -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-xine2' Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-xine2' @@ -263,7 +263,7 @@ After this operation, 258 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." aptget install amarok-xine2/experimental --trivial-only -V -q=0 # sometimes, the second level need to be corrected, too -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-xine3' Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-xine3' @@ -290,7 +290,7 @@ After this operation, 301 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." aptget install amarok-xine3/experimental --trivial-only -V -q=0 # … but proceed testing if the first doesn't work out even in second deep -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-xine4' Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-xine4' @@ -314,7 +314,7 @@ After this operation, 258 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." aptget install amarok-xine4/experimental --trivial-only -V -q=0 # providers can be broken, too -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-broken' Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-broken' @@ -338,7 +338,7 @@ After this operation, 258 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." aptget install amarok-broken/experimental --trivial-only -V -q=0 # switch the candidate for recommends too if they should be installed -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-recommends' Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-recommends' @@ -361,7 +361,7 @@ After this operation, 258 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." aptget install amarok-recommends/experimental --trivial-only -V -q=0 -o APT::Install-Recommends=1 # … or not if not -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-recommends' Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-recommends' @@ -382,7 +382,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a # but broken recommends are not the end of the world # FIXME: the version output for recommend packages is a bit strange… but what would be better? -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-recommends2' Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-recommends2' @@ -404,7 +404,7 @@ After this operation, 215 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation." aptget install amarok-recommends2/experimental --trivial-only -V -q=0 -o APT::Install-Recommends=1 # if one depends doesn't work, we don't need to look deeper… -testequal "Reading package lists... +testfailureequal "Reading package lists... Building dependency tree... Selected version '1.0' (experimental [all]) for 'uninstallablepkg' Some packages could not be installed. This may mean that you have diff --git a/test/integration/test-releasefile-verification b/test/integration/test-releasefile-verification index 3765a4b1f..363b7fe5b 100755 --- a/test/integration/test-releasefile-verification +++ b/test/integration/test-releasefile-verification @@ -33,7 +33,7 @@ prepare() { } installaptold() { - testequal 'Reading package lists... + testsuccessequal 'Reading package lists... Building dependency tree... Suggested packages: aptitude synaptic wajig dpkg-dev apt-doc bzip2 lzma python-apt @@ -46,7 +46,7 @@ Download complete and in download only mode' aptget install apt -dy } installaptnew() { - testequal 'Reading package lists... + testsuccessequal 'Reading package lists... Building dependency tree... Suggested packages: aptitude synaptic wajig dpkg-dev apt-doc bzip2 lzma python-apt @@ -59,7 +59,7 @@ Download complete and in download only mode' aptget install apt -dy } failaptold() { - testequal 'Reading package lists... + testfailureequal 'Reading package lists... Building dependency tree... Suggested packages: aptitude synaptic wajig dpkg-dev apt-doc bzip2 lzma python-apt @@ -73,7 +73,7 @@ E: There are problems and -y was used without --force-yes' aptget install apt -d } failaptnew() { - testequal 'Reading package lists... + testfailureequal 'Reading package lists... Building dependency tree... Suggested packages: aptitude synaptic wajig dpkg-dev apt-doc bzip2 lzma python-apt @@ -119,7 +119,7 @@ runtest() { find aptarchive/ -name "$DELETEFILE" -delete msgtest 'Cold archive signed by' 'Joe Sixpack' updatesuccess - testequal "$(cat ${PKGFILE}) + testsuccessequal "$(cat ${PKGFILE}) " aptcache show apt installaptold @@ -128,7 +128,7 @@ runtest() { find aptarchive/ -name "$DELETEFILE" -delete msgtest 'Good warm archive signed by' 'Joe Sixpack' updatesuccess - testequal "$(cat ${PKGFILE}-new) + testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt installaptnew @@ -139,7 +139,7 @@ runtest() { find aptarchive/ -name "$DELETEFILE" -delete msgtest 'Cold archive signed by' 'Rex Expired' updatefailure '^W: .* KEYEXPIRED' - testequal "$(cat ${PKGFILE}) + testsuccessequal "$(cat ${PKGFILE}) " aptcache show apt failaptold rm rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg @@ -150,7 +150,7 @@ runtest() { find aptarchive/ -name "$DELETEFILE" -delete msgtest 'Cold archive signed by' 'Marvin Paranoid' updatefailure '^W: .* NO_PUBKEY' - testequal "$(cat ${PKGFILE}) + testsuccessequal "$(cat ${PKGFILE}) " aptcache show apt failaptold @@ -164,7 +164,7 @@ runtest() { find aptarchive/ -name "$DELETEFILE" -delete msgtest 'Bad warm archive signed by' 'Joe Sixpack' updatesuccess - testequal "$(cat ${PKGFILE}-new) + testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt installaptnew @@ -175,7 +175,7 @@ runtest() { find aptarchive/ -name "$DELETEFILE" -delete msgtest 'Cold archive signed by' 'Joe Sixpack' updatesuccess - testequal "$(cat ${PKGFILE}) + testsuccessequal "$(cat ${PKGFILE}) " aptcache show apt installaptold @@ -184,7 +184,7 @@ runtest() { find aptarchive/ -name "$DELETEFILE" -delete msgtest 'Good warm archive signed by' 'Marvin Paranoid' updatefailure '^W: .* NO_PUBKEY' - testequal "$(cat ${PKGFILE}) + testsuccessequal "$(cat ${PKGFILE}) " aptcache show apt installaptold @@ -194,7 +194,7 @@ runtest() { find aptarchive/ -name "$DELETEFILE" -delete msgtest 'Good warm archive signed by' 'Rex Expired' updatefailure '^W: .* KEYEXPIRED' - testequal "$(cat ${PKGFILE}) + testsuccessequal "$(cat ${PKGFILE}) " aptcache show apt installaptold rm rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg @@ -204,7 +204,7 @@ runtest() { find aptarchive/ -name "$DELETEFILE" -delete msgtest 'Good warm archive signed by' 'Joe Sixpack' updatesuccess - testequal "$(cat ${PKGFILE}-new) + testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt installaptnew } @@ -223,7 +223,7 @@ runtest2() { find aptarchive/ -name Release.gpg -delete msgtest 'Warm archive signed by' 'nobody' updatesuccess - testequal "$(cat ${PKGFILE}-new) + testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt failaptnew @@ -231,7 +231,7 @@ runtest2() { rm -rf rootdir/var/lib/apt/lists msgtest 'Cold archive signed by' 'nobody' updatesuccess - testequal "$(cat ${PKGFILE}-new) + testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt failaptnew } diff --git a/test/integration/test-resolve-by-keep-new-recommends b/test/integration/test-resolve-by-keep-new-recommends index 6b1772877..a8ab9057c 100755 --- a/test/integration/test-resolve-by-keep-new-recommends +++ b/test/integration/test-resolve-by-keep-new-recommends @@ -17,5 +17,5 @@ Calculating upgrade... The following packages have been kept back: foo 0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded." -testequal "$UPGRADE_KEEP" aptget upgrade -s +testsuccessequal "$UPGRADE_KEEP" aptget upgrade -s diff --git a/test/integration/test-sourceslist-trusted-options b/test/integration/test-sourceslist-trusted-options index 55d4e0233..5fe4933ce 100755 --- a/test/integration/test-sourceslist-trusted-options +++ b/test/integration/test-sourceslist-trusted-options @@ -15,7 +15,7 @@ setupaptarchive --no-update APTARCHIVE=$(readlink -f ./aptarchive) everythingsucceeds() { - testequal 'Listing... + testsuccessequal 'Listing... foo/testing 2 amd64 foo/stable 1 amd64 ' apt list foo -a @@ -32,7 +32,7 @@ foo/stable 1 amd64 } everythingfails() { - testequal 'Listing... + testsuccessequal 'Listing... foo/testing 2 amd64 foo/stable 1 amd64 ' apt list foo -a diff --git a/test/integration/test-specific-architecture-dependencies b/test/integration/test-specific-architecture-dependencies index 078a84654..cb6bc3cc2 100755 --- a/test/integration/test-specific-architecture-dependencies +++ b/test/integration/test-specific-architecture-dependencies @@ -30,7 +30,7 @@ insertpackage 'unstable' 'foo-no-conflictor' 'i386' '1' 'Conflicts: foo:i386' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: libc6:i386 @@ -42,7 +42,7 @@ Conf libc6:i386 (1 unstable [i386]) Inst pre-depender (1 unstable [all]) Conf pre-depender (1 unstable [all])' aptget install pre-depender -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: libc6:i386 @@ -54,7 +54,7 @@ Inst depender (1 unstable [all]) Conf libc6:i386 (1 unstable [i386]) Conf depender (1 unstable [all])' aptget install depender -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following packages will be REMOVED: libold libold:i386 @@ -66,7 +66,7 @@ Remv libold:i386 [1] Inst breaker (1 unstable [all]) Conf breaker (1 unstable [all])' aptget install breaker -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following packages will be REMOVED: libold:i386 @@ -77,7 +77,7 @@ Remv libold:i386 [1] Inst breaker-x32 (1 unstable [amd64]) Conf breaker-x32 (1 unstable [amd64])' aptget install breaker-x32 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following packages will be REMOVED: libold @@ -88,7 +88,7 @@ Remv libold [1] Inst breaker-x64:i386 (1 unstable [i386]) Conf breaker-x64:i386 (1 unstable [i386])' aptget install breaker-x64 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: oldconflictor @@ -96,7 +96,7 @@ The following NEW packages will be installed: Inst oldconflictor (1 unstable [all]) Conf oldconflictor (1 unstable [all])' aptget install oldconflictor -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: oldconflictor-x32 @@ -104,7 +104,7 @@ The following NEW packages will be installed: Inst oldconflictor-x32 (1 unstable [amd64]) Conf oldconflictor-x32 (1 unstable [amd64])' aptget install oldconflictor-x32 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: oldconflictor-x64:i386 @@ -112,7 +112,7 @@ The following NEW packages will be installed: Inst oldconflictor-x64:i386 (1 unstable [i386]) Conf oldconflictor-x64:i386 (1 unstable [i386])' aptget install oldconflictor-x64 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo-depender @@ -120,7 +120,7 @@ The following NEW packages will be installed: Inst foo-depender (1 unstable [amd64]) Conf foo-depender (1 unstable [amd64])' aptget install foo-depender -s -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable @@ -132,7 +132,7 @@ The following packages have unmet dependencies: foo-depender:i386 : Depends: foo:i386 but it is not installable E: Unable to correct problems, you have held broken packages.' aptget install foo-depender:i386 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo-foreign-depender:i386 @@ -140,7 +140,7 @@ The following NEW packages will be installed: Inst foo-foreign-depender:i386 (1 unstable [i386]) Conf foo-foreign-depender:i386 (1 unstable [i386])' aptget install foo-foreign-depender:i386 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following packages will be REMOVED: provider @@ -151,7 +151,7 @@ Remv provider [1] Inst foo-conflictor (1 unstable [amd64]) Conf foo-conflictor (1 unstable [amd64])' aptget install foo-conflictor -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following packages will be REMOVED: provider @@ -162,7 +162,7 @@ Remv provider [1] Inst foo-conflictor:i386 (1 unstable [i386]) Conf foo-conflictor:i386 (1 unstable [i386])' aptget install foo-conflictor:i386 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following packages will be REMOVED: provider @@ -173,7 +173,7 @@ Remv provider [1] Inst foo-foreign-conflictor:i386 (1 unstable [i386]) Conf foo-foreign-conflictor:i386 (1 unstable [i386])' aptget install foo-foreign-conflictor:i386 -s -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo-no-conflictor:i386 diff --git a/test/integration/test-suggest-installed-multiarch-silbing b/test/integration/test-suggest-installed-multiarch-silbing index 89640a30c..f2b1db5eb 100755 --- a/test/integration/test-suggest-installed-multiarch-silbing +++ b/test/integration/test-suggest-installed-multiarch-silbing @@ -26,26 +26,26 @@ insertpackage 'unstable' 'mozplugger' 'i386,amd64' '1' 'Depends: iceweasel | fir setupaptarchive -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Package 'foo' is not installed, so not removed. Did you mean 'foo:i386'? 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove foo -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... The following packages will be REMOVED: foo2:i386 0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded. Remv foo2:i386 [1]" aptget remove foo2 -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... The following packages will be REMOVED: foo3 0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded. Remv foo3 [1]" aptget remove foo3 -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Package 'foo3:i386' is not installed, so not removed. Did you mean 'foo3'? 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove foo3:i386 -s @@ -58,22 +58,22 @@ Building dependency tree... Package 'samefoo:armel' is not installed, so not removed. Did you mean 'samefoo:i386'? 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove samefoo:armel -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Package 'samefoo2' is not installed, so not removed. Did you mean 'samefoo2:i386'? 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove samefoo2 -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Package 'samefoo2:armel' is not installed, so not removed. Did you mean 'samefoo2:i386'? 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove samefoo2:armel -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Package 'iceweasel' is not installed, so not removed 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove iceweasel -s -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Package 'fireweasel' is not installed, so not removed. Did you mean 'fireweasel:i386'? 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove fireweasel:amd64 -s diff --git a/test/integration/test-ubuntu-bug-1098738-apt-get-source-md5sum b/test/integration/test-ubuntu-bug-1098738-apt-get-source-md5sum index 574183b0a..ec74a750b 100755 --- a/test/integration/test-ubuntu-bug-1098738-apt-get-source-md5sum +++ b/test/integration/test-ubuntu-bug-1098738-apt-get-source-md5sum @@ -145,7 +145,7 @@ cd downloaded testok() { rm -f ${1}_1.0.dsc ${1}_1.0.tar.gz - testequal "Reading package lists... + testsuccessequal "Reading package lists... Building dependency tree... Need to get 6 B of source archives. Get:1 http://localhost:8080/ $1 1.0 (dsc) [3 B] @@ -159,7 +159,7 @@ Download complete and in download only mode" aptget source -d "$@" testkeep() { echo -n 'dsc' > ${1}_1.0.dsc echo -n 'tar' > ${1}_1.0.tar.gz - testequal "Reading package lists... + testsuccessequal "Reading package lists... Building dependency tree... Skipping already downloaded file '${1}_1.0.dsc' Skipping already downloaded file '${1}_1.0.tar.gz' @@ -172,7 +172,7 @@ Download complete and in download only mode" aptget source -d "$@" testmismatch() { rm -f ${1}_1.0.dsc ${1}_1.0.tar.gz - testequal "Reading package lists... + testfailureequal "Reading package lists... Building dependency tree... Need to get 6 B of source archives. Get:1 http://localhost:8080/ $1 1.0 (dsc) [3 B] @@ -186,7 +186,7 @@ E: Failed to fetch some archives." aptget source -d "$@" testfailure --nomsg test -e ${1}_1.0.dsc -a -e ${1}_1.0.tar.gz rm -f ${1}_1.0.dsc ${1}_1.0.tar.gz - testequal "Reading package lists... + testsuccessequal "Reading package lists... Building dependency tree... Skipping download of file 'pkg-sha256-bad_1.0.dsc' as requested hashsum is not available for authentication Skipping download of file 'pkg-sha256-bad_1.0.tar.gz' as requested hashsum is not available for authentication @@ -196,7 +196,7 @@ Download complete and in download only mode" aptget source -d "$@" -o Acquire::F testfailure --nomsg test -e ${1}_1.0.dsc -a -e ${1}_1.0.tar.gz rm -f ${1}_1.0.dsc ${1}_1.0.tar.gz - testequal "Reading package lists... + testsuccessequal "Reading package lists... Building dependency tree... Need to get 6 B of source archives. Get:1 http://localhost:8080/ $1 1.0 (dsc) [3 B] @@ -221,7 +221,7 @@ testok pkg-sha256-bad -o Acquire::ForceHash=MD5Sum # not having MD5 sum doesn't mean the file doesn't exist at all … testok pkg-no-md5 testok pkg-no-md5 -o Acquire::ForceHash=SHA256 -testequal "Reading package lists... +testsuccessequal "Reading package lists... Building dependency tree... Skipping download of file 'pkg-no-md5_1.0.dsc' as requested hashsum is not available for authentication Skipping download of file 'pkg-no-md5_1.0.tar.gz' as requested hashsum is not available for authentication @@ -233,7 +233,7 @@ testfailure --nomsg test -e pkg-no-md5_1.0.dsc -a -e pkg-no-md5_1.0.tar.gz # deal with cases in which we haven't for all files the same checksum type # mostly pathologic as this shouldn't happen, but just to be sure testok pkg-mixed-ok -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Need to get 6 B of source archives. Get:1 http://localhost:8080/ pkg-mixed-sha1-bad 1.0 (tar) [3 B] @@ -243,7 +243,7 @@ E: Failed to fetch http://localhost:8080/pkg-mixed-sha1-bad_1.0.dsc Hash Sum mi E: Failed to fetch some archives.' aptget source -d pkg-mixed-sha1-bad msgtest 'Only tar file is downloaded as the dsc has hashsum mismatch' 'pkg-mixed-sha1-bad' testsuccess --nomsg test ! -e pkg-mixed-sha1-bad_1.0.dsc -a -e pkg-mixed-sha1-bad_1.0.tar.gz -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Need to get 6 B of source archives. Get:1 http://localhost:8080/ pkg-mixed-sha2-bad 1.0 (tar) [3 B] @@ -256,9 +256,9 @@ testsuccess --nomsg test -e pkg-mixed-sha2-bad_1.0.dsc -a ! -e pkg-mixed-sha2-ba # it gets even more pathologic: multiple entries for one file, some even disagreeing! testok pkg-md5-agree -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... E: Error parsing checksum in Files of source package pkg-md5-disagree' aptget source -d pkg-md5-disagree -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... E: Error parsing checksum in Checksums-SHA256 of source package pkg-sha256-disagree' aptget source -d pkg-sha256-disagree diff --git a/test/integration/test-ubuntu-bug-1130419-prefer-installed-ma-same-siblings b/test/integration/test-ubuntu-bug-1130419-prefer-installed-ma-same-siblings index af6b7b504..192ed5efc 100755 --- a/test/integration/test-ubuntu-bug-1130419-prefer-installed-ma-same-siblings +++ b/test/integration/test-ubuntu-bug-1130419-prefer-installed-ma-same-siblings @@ -20,7 +20,7 @@ insertpackage 'unstable' 'steam' 'i386' '2' 'Depends: libmesa' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: libmesa:i386 @@ -31,7 +31,7 @@ Inst libmesa:i386 (1 stable [i386]) Inst steam:i386 (1 stable [i386]) Conf libmesa:i386 (1 stable [i386]) Conf steam:i386 (1 stable [i386])' aptget install steam -st stable -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: libmesa:i386 @@ -45,7 +45,7 @@ Conf steam:i386 (2 unstable [i386])' aptget install steam -st unstable cp rootdir/var/lib/dpkg/status default-status.dpkg insertinstalledpackage 'libmesa' 'amd64' '1' 'Multi-Arch: same' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: libmesa:i386 @@ -56,7 +56,7 @@ Inst libmesa:i386 (1 stable [i386]) Inst steam:i386 (1 stable [i386]) Conf libmesa:i386 (1 stable [i386]) Conf steam:i386 (1 stable [i386])' aptget install steam -st stable -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: libmesa libmesa:i386 @@ -76,7 +76,7 @@ cp default-status.dpkg rootdir/var/lib/dpkg/status insertinstalledpackage 'libmesa-lts' 'amd64' '1' 'Provides: libmesa Conflicts: libmesa Multi-Arch: same' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: libmesa-lts:i386 @@ -87,7 +87,7 @@ Inst libmesa-lts:i386 (1 stable [i386]) Inst steam:i386 (1 stable [i386]) Conf libmesa-lts:i386 (1 stable [i386]) Conf steam:i386 (1 stable [i386])' aptget install steam -st stable -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: libmesa-lts libmesa-lts:i386 diff --git a/test/integration/test-ubuntu-bug-1304403-obsolete-priority-standard b/test/integration/test-ubuntu-bug-1304403-obsolete-priority-standard index 45f70a898..b4f705d8b 100755 --- a/test/integration/test-ubuntu-bug-1304403-obsolete-priority-standard +++ b/test/integration/test-ubuntu-bug-1304403-obsolete-priority-standard @@ -25,7 +25,7 @@ insertinstalledpackage 'not-downloadable' 'all' '1.0' '' 'standard' setupaptarchive # discourage keeping obsolete high-priority packages … -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be REMOVED: @@ -42,7 +42,7 @@ for i in $(seq 1 10); do insertinstalledpackage "depender$i" 'all' '1.0' 'Depends: not-downloadable' done -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages have been kept back: diff --git a/test/integration/test-ubuntu-bug-614993 b/test/integration/test-ubuntu-bug-614993 index 49955f231..7067713e8 100755 --- a/test/integration/test-ubuntu-bug-614993 +++ b/test/integration/test-ubuntu-bug-614993 @@ -55,5 +55,5 @@ The following packages will be upgraded: Need to get 0 B/5505 kB of archives. After this operation, 2294 kB disk space will be freed. E: Trivial Only specified but this is not a trivial operation." -testequal "$UPGRADE" aptget install xserver-xorg --trivial-only +testfailureequal "$UPGRADE" aptget install xserver-xorg --trivial-only diff --git a/test/integration/test-ubuntu-bug-761175-remove-purge b/test/integration/test-ubuntu-bug-761175-remove-purge index 0b5a91246..c2e2aadf1 100755 --- a/test/integration/test-ubuntu-bug-761175-remove-purge +++ b/test/integration/test-ubuntu-bug-761175-remove-purge @@ -31,7 +31,7 @@ runtests() { testdpkgnotinstalled compiz-core-$1 testdpkgstatus 'rc' '1' "compiz-core-$1" - testequal "Reading package lists... + testsuccessequal "Reading package lists... Building dependency tree... Reading state information... The following packages will be REMOVED: @@ -39,7 +39,7 @@ The following packages will be REMOVED: 0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded. Purg compiz-core-$1" aptget purge compiz-core-$1 -s testsuccess aptget purge compiz-core-$1 -y - testequal "dpkg-query: no packages found matching compiz-core-$1" dpkg -l compiz-core-$1 + testfailureequal "dpkg-query: no packages found matching compiz-core-$1" dpkg -l compiz-core-$1 } msgmsg 'Test in multi arch environment' diff --git a/test/integration/test-ubuntu-bug-784473-InRelease-one-message-only b/test/integration/test-ubuntu-bug-784473-InRelease-one-message-only index 09315868b..754487a90 100755 --- a/test/integration/test-ubuntu-bug-784473-InRelease-one-message-only +++ b/test/integration/test-ubuntu-bug-784473-InRelease-one-message-only @@ -31,7 +31,7 @@ msgtest 'The unsigned garbage before signed block is' 'ignored' aptget update -qq 2>&1 | grep -q 'W:.*Does not start with a cleartext signature' && msgpass || msgfail ROOTDIR="$(readlink -f .)" -testequal "Package files: +testsuccessequal "Package files: 100 ${ROOTDIR}/rootdir/var/lib/dpkg/status release a=now Pinned packages:" aptcache policy diff --git a/test/integration/test-ubuntu-bug-802901-multiarch-early-remove b/test/integration/test-ubuntu-bug-802901-multiarch-early-remove index bdb4e5e4f..f56ff020c 100755 --- a/test/integration/test-ubuntu-bug-802901-multiarch-early-remove +++ b/test/integration/test-ubuntu-bug-802901-multiarch-early-remove @@ -15,7 +15,7 @@ Conflicts: libgl1' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: libgl1-mesa-glx:i386 diff --git a/test/integration/test-ubuntu-bug-806274-install-suggests b/test/integration/test-ubuntu-bug-806274-install-suggests index fb72f0999..3f02316f4 100755 --- a/test/integration/test-ubuntu-bug-806274-install-suggests +++ b/test/integration/test-ubuntu-bug-806274-install-suggests @@ -15,7 +15,7 @@ insertpackage 'unstable' 'baz' 'i386' '1.0' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: bar foo @@ -32,7 +32,7 @@ Inst bar (1.0 unstable [i386]) Conf bar (1.0 unstable [i386])' aptget install apt -s --install-recommends --no-install-suggests -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: bar baz foo @@ -48,7 +48,7 @@ Inst baz (1.0 unstable [i386]) Conf bar (1.0 unstable [i386]) Conf baz (1.0 unstable [i386])' aptget install apt -s --install-recommends --install-suggests -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: foo @@ -64,7 +64,7 @@ Conf foo (1.0 unstable [i386]) Inst apt (0.8.15 unstable [i386]) Conf apt (0.8.15 unstable [i386])' aptget install apt -s --no-install-recommends --no-install-suggests -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: baz foo diff --git a/test/integration/test-ubuntu-bug-859188-multiarch-reinstall b/test/integration/test-ubuntu-bug-859188-multiarch-reinstall index be86f2e91..9bb99305e 100755 --- a/test/integration/test-ubuntu-bug-859188-multiarch-reinstall +++ b/test/integration/test-ubuntu-bug-859188-multiarch-reinstall @@ -21,7 +21,7 @@ Inst libsame:i386 [1.0] (1.0 unstable [i386]) Conf libsame (1.0 unstable [amd64]) Conf libsame:i386 (1.0 unstable [i386])' -testequal "$REINSTALL" aptget install --reinstall libsame -s -testequal "$REINSTALL" aptget install --reinstall libsame:amd64 -s -testequal "$REINSTALL" aptget install --reinstall libsame:i386 -s -testequal "$REINSTALL" aptget install --reinstall libsame:amd64 libsame:i386 -s +testsuccessequal "$REINSTALL" aptget install --reinstall libsame -s +testsuccessequal "$REINSTALL" aptget install --reinstall libsame:amd64 -s +testsuccessequal "$REINSTALL" aptget install --reinstall libsame:i386 -s +testsuccessequal "$REINSTALL" aptget install --reinstall libsame:amd64 libsame:i386 -s diff --git a/test/integration/test-ubuntu-bug-985852-pre-depends-or-group-ordering b/test/integration/test-ubuntu-bug-985852-pre-depends-or-group-ordering index d2b6b9bad..e9cbf958e 100755 --- a/test/integration/test-ubuntu-bug-985852-pre-depends-or-group-ordering +++ b/test/integration/test-ubuntu-bug-985852-pre-depends-or-group-ordering @@ -12,7 +12,7 @@ insertpackage 'unstable' 'custom' 'amd64' '2.0' 'Pre-Depends: grub-pc | grub' setupaptarchive -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be upgraded: diff --git a/test/integration/test-unpack-different-version-unpacked b/test/integration/test-unpack-different-version-unpacked index 952f6e6b2..ae121cf4e 100755 --- a/test/integration/test-unpack-different-version-unpacked +++ b/test/integration/test-unpack-different-version-unpacked @@ -19,7 +19,7 @@ cleanstatus() { #FIXME: the reported version is wrong, it should be 1, not 2 insertinstalledpackage 'libqtcore4' 'i386,amd64' '1' 'Multi-Arch: same' '' 'install ok unpacked' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... 0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded. 2 not fully installed or removed. @@ -29,7 +29,7 @@ Conf libqtcore4:i386 (2 unstable [i386])' aptget install -s -f cleanstatus insertinstalledpackage 'libqtcore4' 'amd64' '2' 'Multi-Arch: same' '' 'install ok unpacked' insertinstalledpackage 'libqtcore4' 'i386' '1' 'Multi-Arch: same' '' 'install ok unpacked' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Correcting dependencies... Done The following extra packages will be installed: @@ -45,7 +45,7 @@ Conf libqtcore4 (2 unstable [amd64])' aptget install -s -f cleanstatus insertinstalledpackage 'libqtcore4' 'i386' '2' 'Multi-Arch: same' '' 'install ok unpacked' insertinstalledpackage 'libqtcore4' 'amd64' '1' 'Multi-Arch: same' '' 'install ok unpacked' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Correcting dependencies... Done The following extra packages will be installed: @@ -61,7 +61,7 @@ Conf libqtcore4:i386 (2 unstable [i386])' aptget install -s -f cleanstatus insertinstalledpackage 'libqtcore4' 'amd64' '2' 'Multi-Arch: same' '' 'install ok unpacked' insertinstalledpackage 'libqtcore4' 'i386' '1' 'Multi-Arch: same' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Correcting dependencies... Done The following extra packages will be installed: @@ -77,7 +77,7 @@ Conf libqtcore4 (2 unstable [amd64])' aptget install -s -f cleanstatus insertinstalledpackage 'libqtcore4' 'i386' '2' 'Multi-Arch: same' '' 'install ok unpacked' insertinstalledpackage 'libqtcore4' 'amd64' '1' 'Multi-Arch: same' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Correcting dependencies... Done The following extra packages will be installed: @@ -93,7 +93,7 @@ Conf libqtcore4:i386 (2 unstable [i386])' aptget install -s -f cleanstatus insertinstalledpackage 'libqtcore4' 'amd64' '2' 'Multi-Arch: same' insertinstalledpackage 'libqtcore4' 'i386' '1' 'Multi-Arch: same' '' 'install ok unpacked' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Correcting dependencies... Done The following extra packages will be installed: @@ -108,7 +108,7 @@ Conf libqtcore4:i386 (2 unstable [i386])' aptget install -s -f cleanstatus insertinstalledpackage 'libqtcore4' 'i386' '2' 'Multi-Arch: same' insertinstalledpackage 'libqtcore4' 'amd64' '1' 'Multi-Arch: same' '' 'install ok unpacked' -testequal 'Reading package lists... +testsuccessequal 'Reading package lists... Building dependency tree... Correcting dependencies... Done The following extra packages will be installed: diff --git a/test/integration/test-xorg-break-providers b/test/integration/test-xorg-break-providers index 0be57d979..ff1f3b077 100755 --- a/test/integration/test-xorg-break-providers +++ b/test/integration/test-xorg-break-providers @@ -13,7 +13,7 @@ setupaptarchive # The test ensures that only -intel will be upgraded # (together with -core of course) and -vesa not touched. -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... The following extra packages will be installed: xserver-xorg-video-intel @@ -24,7 +24,7 @@ Need to get 0 B/2992 kB of archives. After this operation, 24.6 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation.' aptget install xserver-xorg-core --trivial-only -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be upgraded: @@ -34,7 +34,7 @@ Need to get 0 B/2992 kB of archives. After this operation, 24.6 kB of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation.' aptget upgrade --trivial-only -testequal 'Reading package lists... +testfailureequal 'Reading package lists... Building dependency tree... Calculating upgrade... The following packages will be upgraded: -- cgit v1.2.3-70-g09d2 From 27925d82dd0cbae74d48040363fe6f6c2bae5215 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 27 Mar 2015 15:53:43 +0100 Subject: improve https method queue progress reporting The worker expects that the methods tell him when they start or finish downloading a file. Various information pieces are passed along in this report including the (expected) filesize. https was using a "global" struct for reporting which made it 'reuse' incorrect values in some cases like a non-existent InRelease fallbacking to Release{,.gpg} resulting in a size-mismatch warning. Reducing the scope and redesigning the setting of the values we can fix this and related issues. Closes: 777565, 781509 Thanks: Robert Edmonds and Anders Kaseorg for initial patchs --- methods/https.cc | 82 ++++++++++----------- methods/https.h | 2 +- methods/server.h | 3 +- test/integration/framework | 20 +++++- test/integration/test-apt-https-no-redirect | 15 ++-- test/integration/test-apt-update-expected-size | 86 +++++++++++++++-------- test/integration/test-bug-602412-dequote-redirect | 3 +- 7 files changed, 121 insertions(+), 90 deletions(-) (limited to 'test/integration/framework') diff --git a/methods/https.cc b/methods/https.cc index c69e84d3a..70f6a1046 100644 --- a/methods/https.cc +++ b/methods/https.cc @@ -37,11 +37,17 @@ /*}}}*/ using namespace std; +struct APT_HIDDEN CURLUserPointer { + HttpsMethod * const https; + HttpsMethod::FetchResult * const Res; + CURLUserPointer(HttpsMethod * const https, HttpsMethod::FetchResult * const Res) : https(https), Res(Res) {} +}; + size_t HttpsMethod::parse_header(void *buffer, size_t size, size_t nmemb, void *userp) { size_t len = size * nmemb; - HttpsMethod *me = (HttpsMethod *)userp; + CURLUserPointer *me = (CURLUserPointer *)userp; std::string line((char*) buffer, len); for (--len; len > 0; --len) if (isspace(line[len]) == 0) @@ -53,23 +59,33 @@ HttpsMethod::parse_header(void *buffer, size_t size, size_t nmemb, void *userp) if (line.empty() == true) { - if (me->Server->Result != 416 && me->Server->StartPos != 0) + if (me->https->Server->Result != 416 && me->https->Server->StartPos != 0) ; - else if (me->Server->Result == 416 && me->Server->Size == me->File->FileSize()) + else if (me->https->Server->Result == 416 && me->https->Server->Size == me->https->File->FileSize()) { - me->Server->Result = 200; - me->Server->StartPos = me->Server->Size; + me->https->Server->Result = 200; + me->https->Server->StartPos = me->https->Server->Size; // the actual size is not important for https as curl will deal with it // by itself and e.g. doesn't bother us with transport-encoding… - me->Server->JunkSize = std::numeric_limits::max(); + me->https->Server->JunkSize = std::numeric_limits::max(); } else - me->Server->StartPos = 0; + me->https->Server->StartPos = 0; + + me->https->File->Truncate(me->https->Server->StartPos); + me->https->File->Seek(me->https->Server->StartPos); + + me->Res->LastModified = me->https->Server->Date; + me->Res->Size = me->https->Server->Size; + me->Res->ResumePoint = me->https->Server->StartPos; - me->File->Truncate(me->Server->StartPos); - me->File->Seek(me->Server->StartPos); + // we expect valid data, so tell our caller we get the file now + if (me->https->Server->Result >= 200 && me->https->Server->Result < 300 && + me->https->Server->JunkSize == 0 && + me->Res->Size != 0 && me->Res->Size > me->Res->ResumePoint) + me->https->URIStart(*me->Res); } - else if (me->Server->HeaderLine(line) == false) + else if (me->https->Server->HeaderLine(line) == false) return 0; return size*nmemb; @@ -85,12 +101,6 @@ HttpsMethod::write_data(void *buffer, size_t size, size_t nmemb, void *userp) if (me->Server->JunkSize != 0) return buffer_size; - if (me->Server->ReceivedData == false) - { - me->URIStart(me->Res); - me->Server->ReceivedData = true; - } - if(me->File->Write(buffer, buffer_size) != true) return 0; @@ -109,27 +119,15 @@ HttpsMethod::write_data(void *buffer, size_t size, size_t nmemb, void *userp) return buffer_size; } -int -HttpsMethod::progress_callback(void *clientp, double dltotal, double /*dlnow*/, - double /*ultotal*/, double /*ulnow*/) -{ - HttpsMethod *me = (HttpsMethod *)clientp; - if(dltotal > 0 && me->Res.Size == 0) { - me->Res.Size = (unsigned long long)dltotal; - } - return 0; -} - // HttpsServerState::HttpsServerState - Constructor /*{{{*/ HttpsServerState::HttpsServerState(URI Srv,HttpsMethod * Owner) : ServerState(Srv, Owner) { TimeOut = _config->FindI("Acquire::https::Timeout",TimeOut); - ReceivedData = false; Reset(); } /*}}}*/ -void HttpsMethod::SetupProxy() /*{{{*/ +void HttpsMethod::SetupProxy() /*{{{*/ { URI ServerName = Queue->Uri; @@ -207,16 +205,16 @@ bool HttpsMethod::Fetch(FetchItem *Itm) maybe_add_auth (Uri, _config->FindFile("Dir::Etc::netrc")); + FetchResult Res; + CURLUserPointer userp(this, &Res); // callbacks curl_easy_setopt(curl, CURLOPT_URL, static_cast(Uri).c_str()); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, parse_header); - curl_easy_setopt(curl, CURLOPT_WRITEHEADER, this); + curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &userp); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, this); - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback); - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, this); // options - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, true); curl_easy_setopt(curl, CURLOPT_FILETIME, true); // only allow curl to handle https, not the other stuff it supports curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); @@ -414,24 +412,23 @@ bool HttpsMethod::Fetch(FetchItem *Itm) return false; } - struct stat resultStat; - if (unlikely(stat(File->Name().c_str(), &resultStat) != 0)) - { - _error->Errno("stat", "Unable to access file %s", File->Name().c_str()); - return false; - } - Res.Size = resultStat.st_size; - // invalid range-request if (Server->Result == 416) { unlink(File->Name().c_str()); - Res.Size = 0; delete File; Redirect(Itm->Uri); return true; } + struct stat resultStat; + if (unlikely(stat(File->Name().c_str(), &resultStat) != 0)) + { + _error->Errno("stat", "Unable to access file %s", File->Name().c_str()); + return false; + } + Res.Size = resultStat.st_size; + // Timestamp curl_easy_getinfo(curl, CURLINFO_FILETIME, &Res.LastModified); if (Res.LastModified != -1) @@ -455,7 +452,6 @@ bool HttpsMethod::Fetch(FetchItem *Itm) URIDone(Res); // cleanup - Res.Size = 0; delete File; return true; diff --git a/methods/https.h b/methods/https.h index 433a84680..4cc48fc34 100644 --- a/methods/https.h +++ b/methods/https.h @@ -65,7 +65,6 @@ class HttpsMethod : public ServerMethod double ultotal, double ulnow); void SetupProxy(); CURL *curl; - FetchResult Res; ServerState *Server; // Used by ServerMethods unused by https @@ -77,6 +76,7 @@ class HttpsMethod : public ServerMethod virtual bool Configuration(std::string Message); virtual ServerState * CreateServerState(URI uri); + using pkgAcqMethod::FetchResult; HttpsMethod() : ServerMethod("1.2",Pipeline | SendConfig), File(NULL) { diff --git a/methods/server.h b/methods/server.h index 3b232dcac..b974ec89a 100644 --- a/methods/server.h +++ b/methods/server.h @@ -37,7 +37,6 @@ struct ServerState unsigned long long Size; // size of the usable content (aka: the file) unsigned long long JunkSize; // size of junk content (aka: server error pages) unsigned long long StartPos; - bool ReceivedData; time_t Date; bool HaveContent; enum {Chunked,Stream,Closes} Encoding; @@ -76,7 +75,7 @@ struct ServerState bool Comp(URI Other) const {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;}; virtual void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; Size = 0; JunkSize = 0; - StartPos = 0; ReceivedData = false; Encoding = Closes; time(&Date); HaveContent = false; + StartPos = 0; Encoding = Closes; time(&Date); HaveContent = false; State = Header; Persistent = false; Pipeline = true; MaximumSize = 0;}; virtual bool WriteResponse(std::string const &Data) = 0; diff --git a/test/integration/framework b/test/integration/framework index ec23e41e6..50c027a2c 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1125,8 +1125,10 @@ acquire::cdrom::autodetect 0;" > rootdir/etc/apt/apt.conf.d/00cdrom downloadfile() { local PROTO="${1%%:*}" - apthelper -o Debug::Acquire::${PROTO}=1 -o Debug::pkgAcquire::Worker=1 \ - download-file "$1" "$2" 2>&1 || true + if ! apthelper -o Debug::Acquire::${PROTO}=1 -o Debug::pkgAcquire::Worker=1 \ + download-file "$1" "$2" 2>&1 ; then + return 1 + fi # only if the file exists the download was successful if [ -r "$2" ]; then return 0 @@ -1407,6 +1409,20 @@ testfailureequal() { testfileequal "${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailure.output" "$CMP" } +testfailuremsg() { + local CMP="$1" + shift + testfailure "$@" + msgtest 'Check that the output of the previous failed command has expected' 'failures and warnings' + grep '^\(W\|E\):' "${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailure.output" > "${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailureequal.output" 2>&1 || true + if echo "$CMP" | checkdiff - "${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailureequal.output"; then + msgpass + else + echo '### Complete output ###' + cat "${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailure.output" + msgfail + fi +} testfilestats() { msgtest "Test that file $1 has $2 $3" "$4" diff --git a/test/integration/test-apt-https-no-redirect b/test/integration/test-apt-https-no-redirect index bc744d6f2..c91c78916 100755 --- a/test/integration/test-apt-https-no-redirect +++ b/test/integration/test-apt-https-no-redirect @@ -14,22 +14,15 @@ echo 'alright' > aptarchive/working changetohttpswebserver -o 'aptwebserver::redirect::replace::/redirectme/=http://localhost:8080/' msgtest 'download of a file works via' 'http' -downloadfile 'http://localhost:8080/working' httpfile >/dev/null 2>&1 && msgpass || msgfail +testsuccess --nomsg downloadfile 'http://localhost:8080/working' httpfile testfileequal httpfile 'alright' msgtest 'download of a file works via' 'https' -downloadfile 'https://localhost:4433/working' httpsfile >/dev/null 2>&1 && msgpass || msgfail +testsuccess --nomsg downloadfile 'https://localhost:4433/working' httpsfile testfileequal httpsfile 'alright' msgtest 'download of a file does not work if' 'https redirected to http' -downloadfile 'https://localhost:4433/redirectme/working' redirectfile >curloutput 2>&1 && msgfail || msgpass +testfailure --nomsg downloadfile 'https://localhost:4433/redirectme/working' redirectfile msgtest 'libcurl has forbidden access in last request to' 'http resource' -if grep -q -E -- 'Protocol "?http"? not supported or disabled in libcurl' curloutput; then - msgpass -else - cat curloutput - msgfail -fi - - +testsuccess --nomsg grep -q -E -- 'Protocol "?http"? not supported or disabled in libcurl' rootdir/tmp/testfailure.output diff --git a/test/integration/test-apt-update-expected-size b/test/integration/test-apt-update-expected-size index 9711c293a..22de13ea5 100755 --- a/test/integration/test-apt-update-expected-size +++ b/test/integration/test-apt-update-expected-size @@ -10,35 +10,61 @@ configarchitecture "i386" insertpackage 'unstable' 'apt' 'all' '1.0' setupaptarchive --no-update +cp -a aptarchive/dists aptarchive/dists.good + +test_inreleasetoobig() { + # make InRelease really big to trigger fallback + dd if=/dev/zero of=aptarchive/dists/unstable/InRelease bs=1M count=2 2>/dev/null + touch -d '+1hour' aptarchive/dists/unstable/InRelease + testsuccess aptget update -o Apt::Get::List-Cleanup=0 -o acquire::MaxReleaseFileSize=$((1*1000*1000)) -o Debug::pkgAcquire::worker=0 + msgtest 'Check that the max write warning is triggered' + cp rootdir/tmp/testsuccess.output update.output + testsuccess --nomsg grep -q 'Writing more data than expected' update.output + rm -f update.output + # ensure the failed InRelease file got renamed + testsuccess ls rootdir/var/lib/apt/lists/partial/*InRelease.FAILED +} + +test_packagestoobig() { + # append junk at the end of the Packages.gz/Packages + SIZE="$(stat --printf=%s aptarchive/dists/unstable/main/binary-i386/Packages)" + find aptarchive/dists -name 'Packages*' | while read pkg; do + echo "1234567890" >> "$pkg" + touch -d '+1hour' "$pkg" + done + NEW_SIZE="$(stat --printf=%s aptarchive/dists/unstable/main/binary-i386/Packages)" + testfailuremsg "W: Failed to fetch ${1}/dists/unstable/main/binary-i386/Packages Writing more data than expected ($NEW_SIZE > $SIZE) +E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -o Debug::pkgAcquire::Worker=0 +} + +methodtest() { + msgmsg 'Test with' "$1" 'and clean start' + rm -rf rootdir/var/lib/apt/lists rootdir/var/lib/apt/lists.good + # normal update works fine + testsuccess aptget update + mv rootdir/var/lib/apt/lists rootdir/var/lib/apt/lists.good + + # starting fresh works + test_inreleasetoobig "$1" + rm -rf aptarchive/dists rootdir/var/lib/apt/lists + cp -a aptarchive/dists.good aptarchive/dists + test_packagestoobig "$1" + rm -rf aptarchive/dists rootdir/var/lib/apt/lists + cp -a aptarchive/dists.good aptarchive/dists + + msgmsg 'Test with' "$1" 'and existing old data' + cp -a rootdir/var/lib/apt/lists.good rootdir/var/lib/apt/lists + test_inreleasetoobig "$1" + rm -rf aptarchive/dists rootdir/var/lib/apt/lists + cp -a rootdir/var/lib/apt/lists.good rootdir/var/lib/apt/lists + cp -a aptarchive/dists.good aptarchive/dists + test_packagestoobig "$1" + rm -rf aptarchive/dists + cp -a aptarchive/dists.good aptarchive/dists +} + changetowebserver +methodtest 'http://localhost:8080' -# normal update works fine -testsuccess aptget update - -# make InRelease really big to trigger fallback -mv aptarchive/dists/unstable/InRelease aptarchive/dists/unstable/InRelease.good -dd if=/dev/zero of=aptarchive/dists/unstable/InRelease bs=1M count=2 2>/dev/null -touch -d '+1hour' aptarchive/dists/unstable/InRelease -testsuccess aptget update -o Apt::Get::List-Cleanup=0 -o acquire::MaxReleaseFileSize=$((1*1000*1000)) -o Debug::pkgAcquire::worker=0 -msgtest 'Check that the max write warning is triggered' -if grep -q "Writing more data than expected" rootdir/tmp/testsuccess.output; then - msgpass -else - cat rootdir/tmp/testsuccess.output - msgfail -fi -# ensure the failed InRelease file got renamed -testsuccess ls rootdir/var/lib/apt/lists/partial/*InRelease.FAILED -mv aptarchive/dists/unstable/InRelease.good aptarchive/dists/unstable/InRelease - - -# append junk at the end of the Packages.gz/Packages -SIZE="$(stat --printf=%s aptarchive/dists/unstable/main/binary-i386/Packages)" -find aptarchive -name 'Packages*' | while read pkg; do - echo "1234567890" >> "$pkg" -done -NEW_SIZE="$(stat --printf=%s aptarchive/dists/unstable/main/binary-i386/Packages)" -rm -f rootdir/var/lib/apt/lists/localhost* -testfailureequal "W: Failed to fetch http://localhost:8080/dists/unstable/main/binary-i386/Packages Writing more data than expected ($NEW_SIZE > $SIZE) - -E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq +changetohttpswebserver +methodtest 'https://localhost:4433' diff --git a/test/integration/test-bug-602412-dequote-redirect b/test/integration/test-bug-602412-dequote-redirect index d3573a79a..384c8b113 100755 --- a/test/integration/test-bug-602412-dequote-redirect +++ b/test/integration/test-bug-602412-dequote-redirect @@ -8,7 +8,7 @@ configarchitecture 'amd64' buildsimplenativepackage 'unrelated' 'all' '0.5~squeeze1' 'unstable' -setupaptarchive +setupaptarchive --no-update changetowebserver -o aptwebserver::redirect::replace::/pool/=/newpool/ \ -o aptwebserver::redirect::replace::/dists/=/newdists/ @@ -16,6 +16,7 @@ mv aptarchive/pool aptarchive/newpool mv aptarchive/dists aptarchive/newdists testrun() { + msgmsg 'Test redirection works in method boundaries' "$1" msgtest 'Test redirection works in' 'apt-get update' testsuccess --nomsg aptget update -- cgit v1.2.3-70-g09d2 From a09f6eb8fc67cd2d836019f448f18580396185e5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 27 Mar 2015 19:59:44 +0100 Subject: send Alt-* info for uncompressed based on any compressions file sends information about the uncompressed file if it can find it as well as for the compressed file. This was done only for gzip so far, but we support more compression types. That this information isn't used a lot is a different story. Git-Dch: Ignore --- methods/file.cc | 43 ++++++++++++++++++-------------- test/integration/framework | 2 +- test/integration/test-compressed-indexes | 2 +- 3 files changed, 26 insertions(+), 21 deletions(-) (limited to 'test/integration/framework') diff --git a/methods/file.cc b/methods/file.cc index 12db62203..5d9d7b951 100644 --- a/methods/file.cc +++ b/methods/file.cc @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -33,7 +34,7 @@ class FileMethod : public pkgAcqMethod public: - FileMethod() : pkgAcqMethod("1.0",SingleInstance | LocalOnly) {}; + FileMethod() : pkgAcqMethod("1.0",SingleInstance | SendConfig | LocalOnly) {}; }; // FileMethod::Fetch - Fetch a file /*{{{*/ @@ -58,27 +59,31 @@ bool FileMethod::Fetch(FetchItem *Itm) if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0) Res.IMSHit = true; } - - // See if we can compute a file without a .gz exentsion - std::string::size_type Pos = File.rfind(".gz"); - if (Pos + 3 == File.length()) + + // See if the uncompressed file exists and reuse it + std::vector extensions = APT::Configuration::getCompressorExtensions(); + for (std::vector::const_iterator ext = extensions.begin(); ext != extensions.end(); ++ext) { - File = std::string(File,0,Pos); - if (stat(File.c_str(),&Buf) == 0) + if (APT::String::Endswith(File, *ext) == true) { - FetchResult AltRes; - AltRes.Size = Buf.st_size; - AltRes.Filename = File; - AltRes.LastModified = Buf.st_mtime; - AltRes.IMSHit = false; - if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0) - AltRes.IMSHit = true; - - URIDone(Res,&AltRes); - return true; - } + std::string const unfile = File.substr(0, File.length() - ext->length() - 1); + if (stat(unfile.c_str(),&Buf) == 0) + { + FetchResult AltRes; + AltRes.Size = Buf.st_size; + AltRes.Filename = unfile; + AltRes.LastModified = Buf.st_mtime; + AltRes.IMSHit = false; + if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0) + AltRes.IMSHit = true; + + URIDone(Res,&AltRes); + return true; + } + // no break here as we could have situations similar to '.gz' vs '.tar.gz' here + } } - + if (Res.Filename.empty() == true) return _error->Error(_("File not found")); diff --git a/test/integration/framework b/test/integration/framework index 50c027a2c..994956b74 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -3,7 +3,7 @@ EXIT_CODE=0 # we all like colorful messages -if [ "$MSGCOLOR" != 'NO' ]; then +if [ "$MSGCOLOR" != 'NO' ] && [ "$MSGCOLOR" != 'ALWAYS' ]; then if [ ! -t 1 ]; then # but check that we output to a terminal export MSGCOLOR='NO' fi diff --git a/test/integration/test-compressed-indexes b/test/integration/test-compressed-indexes index 5b966754c..c6b292baa 100755 --- a/test/integration/test-compressed-indexes +++ b/test/integration/test-compressed-indexes @@ -61,7 +61,7 @@ testrun() { cd downloaded testsuccess --nomsg aptget download testpkg msgtest '\tdeb file is present'; testsuccess --nomsg test -f testpkg_1.0_i386.deb - rm testpkg_1.0_i386.deb + rm -f testpkg_1.0_i386.deb cd - >/dev/null testsuccessequal 'Reading package lists... Building dependency tree... -- cgit v1.2.3-70-g09d2 From d84da4995df24329e96d57a22136683a9e370f4e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 11 Apr 2015 20:13:19 +0200 Subject: ensure lists/ files have correct permissions after apt-cdrom add Its a bit unpredictable which permissons and owners we will encounter on a CD-ROM (or a USB stick, as apt-cdrom is responsible for those too), so we have to ensure in this codepath as well that everything is nicely setup without waiting for a 'apt-get update' to fix up the (potential) mess. --- apt-pkg/acquire-worker.cc | 14 -------------- apt-pkg/cdrom.cc | 13 ++++--------- apt-pkg/contrib/fileutl.cc | 19 +++++++++++++++++++ apt-pkg/contrib/fileutl.h | 13 ++++++++++++- apt-pkg/indexcopy.cc | 5 ++++- test/integration/framework | 1 + test/integration/test-apt-cdrom | 5 +++-- 7 files changed, 43 insertions(+), 27 deletions(-) (limited to 'test/integration/framework') diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc index f4d1ad412..bee01e620 100644 --- a/apt-pkg/acquire-worker.cc +++ b/apt-pkg/acquire-worker.cc @@ -43,20 +43,6 @@ using namespace std; -static void ChangeOwnerAndPermissionOfFile(char const * const requester, char const * const file, char const * const user, char const * const group, mode_t const mode) /*{{{*/ -{ - if (getuid() == 0 && strlen(user) != 0 && strlen(group) != 0) // if we aren't root, we can't chown, so don't try it - { - // ensure the file is owned by root and has good permissions - struct passwd const * const pw = getpwnam(user); - struct group const * const gr = getgrnam(group); - if (pw != NULL && gr != NULL && chown(file, pw->pw_uid, gr->gr_gid) != 0) - _error->WarningE(requester, "chown to %s:%s of file %s failed", user, group, file); - } - if (chmod(file, mode) != 0) - _error->WarningE(requester, "chmod 0%o of file %s failed", mode, file); -} - /*}}}*/ // Worker::Worker - Constructor for Queue startup /*{{{*/ // --------------------------------------------------------------------- /* */ diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc index 5eccbe5de..8cec4b78e 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -927,8 +927,7 @@ pkgUdevCdromDevices::pkgUdevCdromDevices() /*{{{*/ } /*}}}*/ -bool -pkgUdevCdromDevices::Dlopen() /*{{{*/ +bool pkgUdevCdromDevices::Dlopen() /*{{{*/ { // alread open if(libudev_handle != NULL) @@ -957,18 +956,14 @@ pkgUdevCdromDevices::Dlopen() /*{{{*/ return true; } /*}}}*/ - /*{{{*/ -// convenience interface, this will just call ScanForRemovable -vector -pkgUdevCdromDevices::Scan() +// convenience interface, this will just call ScanForRemovable /*{{{*/ +vector pkgUdevCdromDevices::Scan() { bool CdromOnly = _config->FindB("APT::cdrom::CdromOnly", true); return ScanForRemovable(CdromOnly); } /*}}}*/ - /*{{{*/ -vector -pkgUdevCdromDevices::ScanForRemovable(bool CdromOnly) +vector pkgUdevCdromDevices::ScanForRemovable(bool CdromOnly)/*{{{*/ { vector cdrom_devices; struct udev_enumerate *enumerate; diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 47033eadf..afc243b7f 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -874,6 +874,25 @@ bool StartsWithGPGClearTextSignature(string const &FileName) return true; } /*}}}*/ +// ChangeOwnerAndPermissionOfFile - set file attributes to requested values /*{{{*/ +bool ChangeOwnerAndPermissionOfFile(char const * const requester, char const * const file, char const * const user, char const * const group, mode_t const mode) +{ + if (strcmp(file, "/dev/null") == 0) + return true; + bool Res = true; + if (getuid() == 0 && strlen(user) != 0 && strlen(group) != 0) // if we aren't root, we can't chown, so don't try it + { + // ensure the file is owned by root and has good permissions + struct passwd const * const pw = getpwnam(user); + struct group const * const gr = getgrnam(group); + if (pw != NULL && gr != NULL && chown(file, pw->pw_uid, gr->gr_gid) != 0) + Res &= _error->WarningE(requester, "chown to %s:%s of file %s failed", user, group, file); + } + if (chmod(file, mode) != 0) + Res &= _error->WarningE(requester, "chmod 0%o of file %s failed", mode, file); + return Res; +} + /*}}}*/ class FileFdPrivate { /*{{{*/ public: diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index a64d6cb98..97cb05c56 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -195,10 +195,21 @@ pid_t ExecFork(std::set keep_fds); void MergeKeepFdsFromConfiguration(std::set &keep_fds); bool ExecWait(pid_t Pid,const char *Name,bool Reap = false); - // check if the given file starts with a PGP cleartext signature bool StartsWithGPGClearTextSignature(std::string const &FileName); +/** change file attributes to requested known good values + * + * The method skips the user:group setting if not root. + * + * @param requester is printed as functionname in error cases + * @param file is the file to be modified + * @param user is the (new) owner of the file, e.g. _apt + * @param group is the (new) group owning the file, e.g. root + * @param mode is the access mode of the file, e.g. 0644 + */ +bool ChangeOwnerAndPermissionOfFile(char const * const requester, char const * const file, char const * const user, char const * const group, mode_t const mode); + /** * \brief Drop privileges * diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc index 5fa57fd8b..144c508be 100644 --- a/apt-pkg/indexcopy.cc +++ b/apt-pkg/indexcopy.cc @@ -216,6 +216,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector &List, FinalF += URItoFileName(S); if (rename(TargetF.c_str(),FinalF.c_str()) != 0) return _error->Errno("rename","Failed to rename"); + ChangeOwnerAndPermissionOfFile("CopyPackages", FinalF.c_str(), "root", "root", 0644); } /* Mangle the source to be in the proper notation with @@ -546,8 +547,9 @@ bool SigVerify::CopyMetaIndex(string CDROM, string CDName, /*{{{*/ FileFd Rel; Target.Open(TargetF,FileFd::WriteAtomic); Rel.Open(prefix + file,FileFd::ReadOnly); - if (CopyFile(Rel,Target) == false) + if (CopyFile(Rel,Target) == false || Target.Close() == false) return _error->Error("Copying of '%s' for '%s' from '%s' failed", file.c_str(), CDName.c_str(), prefix.c_str()); + ChangeOwnerAndPermissionOfFile("CopyPackages", TargetF.c_str(), "root", "root", 0644); return true; } @@ -760,6 +762,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/ FinalF += URItoFileName(S); if (rename(TargetF.c_str(),FinalF.c_str()) != 0) return _error->Errno("rename","Failed to rename"); + ChangeOwnerAndPermissionOfFile("CopyTranslations", FinalF.c_str(), "root", "root", 0644); } diff --git a/test/integration/framework b/test/integration/framework index 994956b74..642c5f0d0 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1525,6 +1525,7 @@ aptautotest_aptget_update() { done } aptautotest_apt_update() { aptautotest_aptget_update "$@"; } +aptautotest_aptcdrom_add() { aptautotest_aptget_update "$@"; } testaptautotestnodpkgwarning() { local TESTCALL="$1" diff --git a/test/integration/test-apt-cdrom b/test/integration/test-apt-cdrom index 9906795ca..34b35f745 100755 --- a/test/integration/test-apt-cdrom +++ b/test/integration/test-apt-cdrom @@ -33,6 +33,7 @@ aptcdromlog() { test ! -e rootdir/media/cdrom || echo "CD-ROM is mounted, but shouldn't be!" test -e rootdir/media/cdrom-unmounted || echo "Unmounted CD-ROM doesn't exist, but it should!" } +aptautotest_aptcdromlog_add() { aptautotest_aptget_update "$@"; } CDROM_PRE="Using CD-ROM mount point $(readlink -f ./rootdir/media)/cdrom/ Unmounting CD-ROM... @@ -133,13 +134,13 @@ aptcache show testing -o Acquire::Languages=en | grep -q '^Description-en: ' && # ensure cdrom method isn't trying to mount the cdrom mv rootdir/media/cdrom-unmounted rootdir/media/cdrom-ejected -# ensure an update doesn't mess with cdrom sources +msgmsg "ensure an update doesn't mess with cdrom sources" testsuccess aptget update testfileequal rootdir/tmp/testsuccess.output 'Reading package lists...' mv rootdir/media/cdrom-ejected rootdir/media/cdrom-unmounted testcdromusage -# and again to check that it withstands the temptation even if it could mount +msgmsg 'and again to check that it withstands the temptation even if it could mount' testsuccess aptget update testfileequal rootdir/tmp/testsuccess.output 'Reading package lists...' testcdromusage -- cgit v1.2.3-70-g09d2 From ba6b79bd0090077724fa1272ea4d3a31706fcd5a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 12 Apr 2015 17:08:46 +0200 Subject: a hit on Release files means the indexes will be hits too If we get a IMSHit for the Transaction-Manager (= the InRelease file or as its still supported fallback Release + Release.gpg combo) we can assume that every file we would queue based on this manager, but already have locally is current and hence would get an IMSHit, too. We therefore save us and the server the trouble and skip the queuing in this case. Beside speeding up repetative executions of 'apt-get update' this way we also avoid hitting hashsum errors if the indexes are in fact already updated, but the Release file isn't yet as it is the case on well behaving mirrors as Release files is updated last. The implementation is a bit harder than the theory makes it sound as we still have to keep reverifying the Release files (e.g. to detect now expired once to avoid an attacker being able to silently stale us) and have to handle cases in which the Release file hits, but some indexes aren't present (e.g. user added a new foreign architecture). --- apt-pkg/acquire-item.cc | 90 ++++++++++--- apt-pkg/acquire-item.h | 28 ++-- apt-pkg/acquire.h | 1 + test/integration/framework | 19 +-- test/integration/test-apt-update-expected-size | 4 + test/integration/test-apt-update-ims | 150 +++++++++++++++------- test/integration/test-apt-update-not-modified | 45 +++++++ test/integration/test-apt-update-transactions | 7 + test/integration/test-bug-602412-dequote-redirect | 3 - test/integration/test-pdiff-usage | 15 +-- test/interactive-helper/aptwebserver.cc | 9 +- 11 files changed, 273 insertions(+), 98 deletions(-) create mode 100755 test/integration/test-apt-update-not-modified (limited to 'test/integration/framework') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index f30529066..750e7daca 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -213,7 +213,7 @@ void pkgAcquire::Item::Done(string Message,unsigned long long Size,HashStringLis step */ bool pkgAcquire::Item::Rename(string From,string To) { - if (rename(From.c_str(),To.c_str()) == 0) + if (From == To || rename(From.c_str(),To.c_str()) == 0) return true; std::string S; @@ -224,9 +224,41 @@ bool pkgAcquire::Item::Rename(string From,string To) return false; } /*}}}*/ -void pkgAcquire::Item::QueueURI(ItemDesc &Item) /*{{{*/ +// Acquire::Item::QueueURI and specialisations from child classes /*{{{*/ +/* The idea here is that an item isn't queued if it exists on disk and the + transition manager was a hit as this means that the files it contains + the checksums for can't be updated either (or they are and we are asking + for a hashsum mismatch to happen which helps nobody) */ +bool pkgAcquire::Item::QueueURI(ItemDesc &Item) { + std::string const FinalFile = GetFinalFilename(); + if (TransactionManager != NULL && TransactionManager->IMSHit == true && + FileExists(FinalFile) == true) + { + PartialFile = DestFile = FinalFile; + Status = StatDone; + return false; + } + Owner->Enqueue(Item); + return true; +} +/* The transition manager InRelease itself (or its older sisters-in-law + Release & Release.gpg) is always queued as this allows us to rerun gpgv + on it to verify that we aren't stalled with old files */ +bool pkgAcqMetaBase::QueueURI(pkgAcquire::ItemDesc &Item) +{ + Owner->Enqueue(Item); + return true; +} +/* the Diff/Index needs to queue also the up-to-date complete index file + to ensure that the list cleaner isn't eating it */ +bool pkgAcqDiffIndex::QueueURI(pkgAcquire::ItemDesc &Item) +{ + if (pkgAcquire::Item::QueueURI(Item) == true) + return true; + QueueOnIMSHit(); + return false; } /*}}}*/ void pkgAcquire::Item::Dequeue() /*{{{*/ @@ -408,6 +440,14 @@ string pkgAcqDiffIndex::Custom600Headers() return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); } /*}}}*/ +void pkgAcqDiffIndex::QueueOnIMSHit() const /*{{{*/ +{ + // list cleanup needs to know that this file as well as the already + // present index is ours, so we create an empty diff to save it for us + new pkgAcqIndexDiffs(Owner, TransactionManager, Target, + ExpectedHashes, MetaIndexParser); +} + /*}}}*/ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ { // failing here is fine: our caller will take care of trying to @@ -470,11 +510,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ // we have the same sha1 as the server so we are done here if(Debug) std::clog << "pkgAcqDiffIndex: Package file " << CurrentPackagesFile << " is up-to-date" << std::endl; - - // list cleanup needs to know that this file as well as the already - // present index is ours, so we create an empty diff to save it for us - new pkgAcqIndexDiffs(Owner, TransactionManager, Target, - ExpectedHashes, MetaIndexParser); + QueueOnIMSHit(); return true; } @@ -1096,6 +1132,17 @@ void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,HashStri if(Debug) std::clog << "allDone: " << DestFile << "\n" << std::endl; } +} + /*}}}*/ +// AcqBaseIndex - Constructor /*{{{*/ +pkgAcqBaseIndex::pkgAcqBaseIndex(pkgAcquire *Owner, + pkgAcqMetaBase *TransactionManager, + struct IndexTarget const * const Target, + HashStringList const &ExpectedHashes, + indexRecords *MetaIndexParser) +: Item(Owner, ExpectedHashes, TransactionManager), Target(Target), + MetaIndexParser(MetaIndexParser) +{ } /*}}}*/ // AcqBaseIndex::VerifyHashByMetaKey - verify hash for the given metakey /*{{{*/ @@ -1489,6 +1536,19 @@ void pkgAcqIndex::StageDecompressDone(string Message, TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename()); return; +} + /*}}}*/ +// AcqMetaBase - Constructor /*{{{*/ +pkgAcqMetaBase::pkgAcqMetaBase(pkgAcquire *Owner, + const std::vector* IndexTargets, + indexRecords* MetaIndexParser, + std::string const &RealURI, + HashStringList const &ExpectedHashes, + pkgAcqMetaBase *TransactionManager) +: Item(Owner, ExpectedHashes, TransactionManager), + MetaIndexParser(MetaIndexParser), IndexTargets(IndexTargets), + AuthPass(false), RealURI(RealURI), IMSHit(false) +{ } /*}}}*/ // AcqMetaBase::Add - Add a item to the current Transaction /*{{{*/ @@ -1831,13 +1891,7 @@ bool pkgAcqMetaBase::CheckAuthDone(string Message) /*{{{*/ std::cerr << "Signature verification succeeded: " << DestFile << std::endl; - // Download further indexes with verification - // - // it would be really nice if we could simply do - // if (IMSHit == false) QueueIndexes(true) - // and skip the download if the Release file has not changed - // - but right now the list cleaner will needs to be tricked - // to not delete all our packages/source indexes in this case + // Download further indexes with verification QueueIndexes(true); return true; @@ -1908,7 +1962,13 @@ bool pkgAcqMetaBase::CheckDownloadDone(const std::string &Message) // make sure to verify against the right file on I-M-S hit IMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false); if(IMSHit) + { + // for simplicity, the transaction manager is always InRelease + // even if it doesn't exist. + if (TransactionManager != NULL) + TransactionManager->IMSHit = true; DestFile = GetFinalFilename(); + } // set Item to complete as the remaining work is all local (verify etc) Complete = true; @@ -1951,7 +2011,7 @@ void pkgAcqMetaBase::QueueIndexes(bool verify) /*{{{*/ << "Expected Hash:" << std::endl; for (HashStringList::const_iterator hs = ExpectedIndexHashes.begin(); hs != ExpectedIndexHashes.end(); ++hs) std::cerr << "\t- " << hs->toStr() << std::endl; - std::cerr << "For: " << Record->MetaKeyFilename << std::endl; + std::cerr << "For: " << ((Record == NULL) ? "" : Record->MetaKeyFilename) << std::endl; } if (verify == true && ExpectedIndexHashes.empty() == true) diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index c2759b792..148728b3c 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -73,11 +73,16 @@ class pkgAcquire::Item : public WeakPointable pkgAcquire *Owner; /** \brief Insert this item into its owner's queue. + * + * The method is designed to check if the request would end + * in an IMSHit and if it determines that it would, it isn't + * queueing the Item and instead sets it to completion instantly. * * \param Item Metadata about this item (its URI and * description). + * \return true if the item was inserted, false if IMSHit was detected */ - void QueueURI(ItemDesc &Item); + virtual bool QueueURI(ItemDesc &Item); /** \brief Remove this item from its owner's queue. */ void Dequeue(); @@ -392,9 +397,6 @@ class pkgAcqMetaBase : public pkgAcquire::Item /*{{{*/ */ bool AuthPass; - // required to deal gracefully with problems caused by incorrect ims hits - bool IMSHit; - /** \brief The URI of the signature file. Unlike Desc.URI, this is * never modified; it is used to determine the file that is being * downloaded. @@ -457,7 +459,11 @@ class pkgAcqMetaBase : public pkgAcquire::Item /*{{{*/ virtual std::string GetFinalFilename() const; public: + // This refers more to the Transaction-Manager than the actual file + bool IMSHit; + virtual std::string DescURI() {return RealURI; }; + virtual bool QueueURI(pkgAcquire::ItemDesc &Item); // transaction code void Add(Item *I); @@ -479,10 +485,7 @@ class pkgAcqMetaBase : public pkgAcquire::Item /*{{{*/ indexRecords* MetaIndexParser, std::string const &RealURI, HashStringList const &ExpectedHashes=HashStringList(), - pkgAcqMetaBase *TransactionManager=NULL) - : Item(Owner, ExpectedHashes, TransactionManager), - MetaIndexParser(MetaIndexParser), IndexTargets(IndexTargets), - AuthPass(false), IMSHit(false), RealURI(RealURI) {}; + pkgAcqMetaBase *TransactionManager=NULL); }; /*}}}*/ /** \brief An acquire item that downloads the detached signature {{{ @@ -652,9 +655,7 @@ class pkgAcqBaseIndex : public pkgAcquire::Item pkgAcqMetaBase *TransactionManager, struct IndexTarget const * const Target, HashStringList const &ExpectedHashes, - indexRecords *MetaIndexParser) - : Item(Owner, ExpectedHashes, TransactionManager), Target(Target), - MetaIndexParser(MetaIndexParser) {}; + indexRecords *MetaIndexParser); }; /*}}}*/ /** \brief An item that is responsible for fetching an index file of {{{ @@ -691,6 +692,7 @@ class APT_HIDDEN pkgAcqDiffIndex : public pkgAcqBaseIndex /** \brief Get the full pathname of the final file for the current URI */ virtual std::string GetFinalFilename() const; + virtual bool QueueURI(pkgAcquire::ItemDesc &Item); public: // Specialized action members virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf); @@ -714,7 +716,6 @@ class APT_HIDDEN pkgAcqDiffIndex : public pkgAcqBaseIndex * false otherwise. */ bool ParseDiffIndex(std::string IndexDiffFile); - /** \brief Create a new pkgAcqDiffIndex. * @@ -733,6 +734,8 @@ class APT_HIDDEN pkgAcqDiffIndex : public pkgAcqBaseIndex struct IndexTarget const * const Target, HashStringList const &ExpectedHashes, indexRecords *MetaIndexParser); + private: + APT_HIDDEN void QueueOnIMSHit() const; }; /*}}}*/ /** \brief An item that is responsible for fetching client-merge patches {{{ @@ -1008,7 +1011,6 @@ class APT_HIDDEN pkgAcqIndex : public pkgAcqBaseIndex virtual std::string GetFinalFilename() const; public: - // Specialized action members virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf); virtual void Done(std::string Message,unsigned long long Size, diff --git a/apt-pkg/acquire.h b/apt-pkg/acquire.h index f33362922..fc90624e1 100644 --- a/apt-pkg/acquire.h +++ b/apt-pkg/acquire.h @@ -111,6 +111,7 @@ class pkgAcquire struct MethodConfig; struct ItemDesc; friend class Item; + friend class pkgAcqMetaBase; friend class Queue; typedef std::vector::iterator ItemIterator; diff --git a/test/integration/framework b/test/integration/framework index 642c5f0d0..4229ae162 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1005,6 +1005,7 @@ signreleasefiles() { } webserverconfig() { + local WEBSERVER="${3:-http://localhost:8080}" local NOCHECK=false if [ "$1" = '--no-check' ]; then NOCHECK=true @@ -1016,10 +1017,10 @@ webserverconfig() { local URI if [ -n "$2" ]; then msgtest "Set webserver config option '${1}' to" "$2" - URI="http://localhost:8080/_config/set/${1}/${2}" + URI="${WEBSERVER}/_config/set/${1}/${2}" else msgtest 'Clear webserver config option' "${1}" - URI="http://localhost:8080/_config/clear/${1}" + URI="${WEBSERVER}/_config/clear/${1}" fi if downloadfile "$URI" "$STATUS" > "$DOWNLOG"; then msgpass @@ -1467,12 +1468,14 @@ pause() { } listcurrentlistsdirectory() { - find rootdir/var/lib/apt/lists -maxdepth 1 -type d | while read line; do - stat --format '%U:%G:%a:%n' "$line" - done - find rootdir/var/lib/apt/lists -maxdepth 1 \! -type d | while read line; do - stat --format '%U:%G:%a:%s:%y:%n' "$line" - done + { + find rootdir/var/lib/apt/lists -maxdepth 1 -type d | while read line; do + stat --format '%U:%G:%a:%n' "$line" + done + find rootdir/var/lib/apt/lists -maxdepth 1 \! -type d | while read line; do + stat --format '%U:%G:%a:%s:%y:%n' "$line" + done + } | sort } ### convinience hacks ### diff --git a/test/integration/test-apt-update-expected-size b/test/integration/test-apt-update-expected-size index 22de13ea5..9f58308aa 100755 --- a/test/integration/test-apt-update-expected-size +++ b/test/integration/test-apt-update-expected-size @@ -38,6 +38,10 @@ E: Some index files failed to download. They have been ignored, or old ones used } methodtest() { + # less complicated test setup this way + webserverconfig 'aptwebserver::support::modified-since' 'false' "$1" + webserverconfig 'aptwebserver::support::last-modified' 'false' "$1" # curl is clever and sees hits here also + msgmsg 'Test with' "$1" 'and clean start' rm -rf rootdir/var/lib/apt/lists rootdir/var/lib/apt/lists.good # normal update works fine diff --git a/test/integration/test-apt-update-ims b/test/integration/test-apt-update-ims index 0fa882d78..f091bffaa 100755 --- a/test/integration/test-apt-update-ims +++ b/test/integration/test-apt-update-ims @@ -6,85 +6,145 @@ TESTDIR=$(readlink -f $(dirname $0)) setupenvironment configarchitecture 'amd64' -buildsimplenativepackage 'unrelated' 'all' '0.5~squeeze1' 'unstable' +insertpackage 'unstable' 'unrelated' 'all' '0.5~squeeze1' +insertsource 'unstable' 'unrelated' 'all' '0.5~squeeze1' setupaptarchive --no-update changetowebserver runtest() { - configallowinsecurerepositories "${1:-false}" + if [ -n "$1" ]; then + configallowinsecurerepositories 'true' + else + configallowinsecurerepositories 'false' + fi - rm -f rootdir/var/lib/apt/lists/localhost* + rm -rf rootdir/var/lib/apt/lists/ - if [ "$1" = 'true' ]; then - testwarning aptget update - else - testsuccess aptget update + local TEST="test${1:-success}" + $TEST aptget update + if [ "$1" = 'failure' ]; then + # accept the outdated Release file so we can check Hit behaviour + "test${2:-success}" aptget update -o Acquire::Min-ValidTime=99999999999 fi + listcurrentlistsdirectory > listsdir.lst + testsuccess grep '_Packages\(\.gz\)\?$' listsdir.lst + testsuccess grep '_Sources\(\.gz\)\?$' listsdir.lst + testsuccess grep '_Translation-en\(\.gz\)\?$' listsdir.lst # ensure no leftovers in partial - testfailure ls "rootdir/var/lib/apt/lists/partial/*" + testfailure ls 'rootdir/var/lib/apt/lists/partial/*' # check that I-M-S header is kept in redirections - testequal "$EXPECT" aptget update -o Debug::pkgAcquire::Worker=0 -o Debug::Acquire::http=0 - - # ensure that we still do a hash check on ims hit - msgtest 'Test I-M-S' 'reverify' - aptget update -o Debug::pkgAcquire::Auth=1 2>&1 | grep -A2 'ReceivedHash:' | grep -q -- '- SHA' && msgpass || msgfail + echo "$EXPECT" | sed -e 's#(invalid since [^)]\+)#(invalid since)#' > expected.output + $TEST aptget update -o Debug::pkgAcquire::Worker=0 -o Debug::Acquire::http=0 + sed -i -e 's#(invalid since [^)]\+)#(invalid since)#' rootdir/tmp/${TEST}.output + testequal "$(cat expected.output)" cat rootdir/tmp/${TEST}.output + testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" + + # ensure that we still do a hash check for other files on ims hit of Release + if grep -q '^Hit .* \(InRelease\|Release.gpg\)$' expected.output ; then + $TEST aptget update -o Debug::Acquire::gpgv=1 + cp rootdir/tmp/${TEST}.output goodsign.output + testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" + testsuccess grep '^Got GOODSIG, key ID:GOODSIG' goodsign.output + fi # ensure no leftovers in partial - testfailure ls "rootdir/var/lib/apt/lists/partial/*" + testfailure ls 'rootdir/var/lib/apt/lists/partial/*' } -msgmsg "InRelease" -EXPECT="Hit http://localhost:8080 unstable InRelease -Hit http://localhost:8080 unstable/main Sources -Hit http://localhost:8080 unstable/main amd64 Packages -Hit http://localhost:8080 unstable/main Translation-en -Reading package lists..." -# with InRelease +msgmsg 'InRelease' +EXPECT='Hit http://localhost:8080 unstable InRelease +Reading package lists...' +echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex runtest - -# with gzip -echo "Acquire::GzipIndexes "1";" > rootdir/etc/apt/apt.conf.d/02compressindex +echo 'Acquire::GzipIndexes "1";' > rootdir/etc/apt/apt.conf.d/02compressindex runtest -msgmsg "Release/Release.gpg" -# with Release/Release.gpg -EXPECT="Ign http://localhost:8080 unstable InRelease +msgmsg 'Release/Release.gpg' +EXPECT='Ign http://localhost:8080 unstable InRelease 404 Not Found Hit http://localhost:8080 unstable Release Hit http://localhost:8080 unstable Release.gpg -Hit http://localhost:8080 unstable/main Sources -Hit http://localhost:8080 unstable/main amd64 Packages -Hit http://localhost:8080 unstable/main Translation-en -Reading package lists..." - +Reading package lists...' find aptarchive -name 'InRelease' -delete - -echo "Acquire::GzipIndexes "0";" > rootdir/etc/apt/apt.conf.d/02compressindex +echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex runtest - -echo "Acquire::GzipIndexes "1";" > rootdir/etc/apt/apt.conf.d/02compressindex +echo 'Acquire::GzipIndexes "1";' > rootdir/etc/apt/apt.conf.d/02compressindex runtest -# no Release.gpg or InRelease -msgmsg "Release only" +msgmsg 'Release only' EXPECT="Ign http://localhost:8080 unstable InRelease 404 Not Found Hit http://localhost:8080 unstable Release Ign http://localhost:8080 unstable Release.gpg 404 Not Found -Hit http://localhost:8080 unstable/main Sources -Hit http://localhost:8080 unstable/main amd64 Packages -Hit http://localhost:8080 unstable/main Translation-en Reading package lists... W: The data from 'http://localhost:8080 unstable Release.gpg' is not signed. Packages from that repository can not be authenticated." +find aptarchive -name 'Release.gpg' -delete +echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex +runtest 'warning' +echo 'Acquire::GzipIndexes "1";' > rootdir/etc/apt/apt.conf.d/02compressindex +runtest 'warning' + + +# make the release file old +find aptarchive -name '*Release' -exec sed -i \ + -e "s#^Date: .*\$#Date: $(date -d '-2 weeks' '+%a, %d %b %Y %H:%M:%S %Z')#" \ + -e '/^Valid-Until: / d' -e "/^Date: / a\ +Valid-Until: $(date -d '-1 weeks' '+%a, %d %b %Y %H:%M:%S %Z')" '{}' \; +signreleasefiles + +msgmsg 'expired InRelease' +EXPECT='Hit http://localhost:8080 unstable InRelease +E: Release file for http://localhost:8080/dists/unstable/InRelease is expired (invalid since). Updates for this repository will not be applied.' +echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex +runtest 'failure' +echo 'Acquire::GzipIndexes "1";' > rootdir/etc/apt/apt.conf.d/02compressindex +runtest 'failure' + +msgmsg 'expired Release/Release.gpg' +EXPECT='Ign http://localhost:8080 unstable InRelease + 404 Not Found +Hit http://localhost:8080 unstable Release +Hit http://localhost:8080 unstable Release.gpg +E: Release file for http://localhost:8080/dists/unstable/Release.gpg is expired (invalid since). Updates for this repository will not be applied.' +find aptarchive -name 'InRelease' -delete +echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex +runtest 'failure' +echo 'Acquire::GzipIndexes "1";' > rootdir/etc/apt/apt.conf.d/02compressindex +runtest 'failure' +msgmsg 'expired Release only' +EXPECT="Ign http://localhost:8080 unstable InRelease + 404 Not Found +Hit http://localhost:8080 unstable Release +Ign http://localhost:8080 unstable Release.gpg + 404 Not Found +W: The data from 'http://localhost:8080 unstable Release.gpg' is not signed. Packages from that repository can not be authenticated. +E: Release file for http://localhost:8080/dists/unstable/InRelease is expired (invalid since). Updates for this repository will not be applied." find aptarchive -name 'Release.gpg' -delete +echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex +runtest 'failure' 'warning' +echo 'Acquire::GzipIndexes "1";' > rootdir/etc/apt/apt.conf.d/02compressindex +runtest 'failure' 'warning' -echo "Acquire::GzipIndexes "0";" > rootdir/etc/apt/apt.conf.d/02compressindex -runtest "true" -echo "Acquire::GzipIndexes "1";" > rootdir/etc/apt/apt.conf.d/02compressindex -runtest "true" +msgmsg 'no Release at all' +EXPECT="Ign http://localhost:8080 unstable InRelease + 404 Not Found +Ign http://localhost:8080 unstable Release + 404 Not Found +Hit http://localhost:8080 unstable/main Sources +Hit http://localhost:8080 unstable/main amd64 Packages +Hit http://localhost:8080 unstable/main Translation-en +Reading package lists... +W: The repository 'http://localhost:8080 unstable Release' does not have a Release file. This is deprecated, please contact the owner of the repository." +find aptarchive -name '*Release*' -delete +echo 'Acquire::GzipIndexes "0"; +Acquire::PDiffs "0";' > rootdir/etc/apt/apt.conf.d/02compressindex +runtest 'warning' +echo 'Acquire::GzipIndexes "1"; +Acquire::PDiffs "0";' > rootdir/etc/apt/apt.conf.d/02compressindex +runtest 'warning' diff --git a/test/integration/test-apt-update-not-modified b/test/integration/test-apt-update-not-modified new file mode 100755 index 000000000..2dc56e76c --- /dev/null +++ b/test/integration/test-apt-update-not-modified @@ -0,0 +1,45 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework + +setupenvironment +configarchitecture 'amd64' 'i386' + +insertpackage 'unstable' 'apt' 'all' '1.0' + +setupaptarchive --no-update + +methodtest() { + msgmsg 'Test with' "$1" + rm -rf rootdir/var/lib/apt/lists + # get our cache populated + testsuccess aptget update + listcurrentlistsdirectory > listsdir.lst + + # hit again with a good cache + testsuccessequal "Hit $1 unstable InRelease +Reading package lists..." aptget update + testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" + + # drop an architecture, which means the file should be gone now + configarchitecture 'i386' + sed '/_binary-amd64_Packages/ d' listsdir.lst > listsdir-without-amd64.lst + testsuccessequal "Hit $1 unstable InRelease +Reading package lists..." aptget update + testfileequal 'listsdir-without-amd64.lst' "$(listcurrentlistsdirectory)" + + # readd arch so its downloaded again + configarchitecture 'amd64' 'i386' + testsuccessequal "Hit $1 unstable InRelease +Get:1 $1 unstable/main amd64 Packages [$(stat -c '%s' 'aptarchive/dists/unstable/main/binary-amd64/Packages.gz') B] +Reading package lists..." aptget update + testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" +} + +changetowebserver +methodtest 'http://localhost:8080' + +changetohttpswebserver +methodtest 'https://localhost:4433' diff --git a/test/integration/test-apt-update-transactions b/test/integration/test-apt-update-transactions index b325733ac..f028ac0c7 100755 --- a/test/integration/test-apt-update-transactions +++ b/test/integration/test-apt-update-transactions @@ -59,6 +59,13 @@ testsetup() { } testsetup 'file' + changetowebserver +webserverconfig 'aptwebserver::support::modified-since' 'false' "$1" +webserverconfig 'aptwebserver::support::last-modified' 'false' "$1" # curl is clever and sees hits here also + testsetup 'http' +changetohttpswebserver + +testsetup 'https' diff --git a/test/integration/test-bug-602412-dequote-redirect b/test/integration/test-bug-602412-dequote-redirect index 384c8b113..ca2378c19 100755 --- a/test/integration/test-bug-602412-dequote-redirect +++ b/test/integration/test-bug-602412-dequote-redirect @@ -22,9 +22,6 @@ testrun() { # check that I-M-S header is kept in redirections testsuccessequal "Hit $1 unstable InRelease -Hit $1 unstable/main Sources -Hit $1 unstable/main amd64 Packages -Hit $1 unstable/main Translation-en Reading package lists..." aptget update msgtest 'Test redirection works in' 'package download' diff --git a/test/integration/test-pdiff-usage b/test/integration/test-pdiff-usage index 4de07f1ad..5e759e50e 100755 --- a/test/integration/test-pdiff-usage +++ b/test/integration/test-pdiff-usage @@ -14,16 +14,7 @@ changetowebserver PKGFILE="${TESTDIR}/$(echo "$(basename $0)" | sed 's#^test-#Packages-#')" wasmergeused() { - msgtest 'Test for successful execution of' "$*" - local OUTPUT=$(mktemp) - addtrap "rm $OUTPUT;" - if aptget update "$@" >${OUTPUT} 2>&1; then - msgpass - else - echo - cat $OUTPUT - msgfail - fi + testsuccess aptget update "$@" msgtest 'No intermediate patch files' 'still exist' local EDS="$(find rootdir/var/lib/apt/lists -name '*.ed' -o -name '*.ed.*')" @@ -36,7 +27,7 @@ wasmergeused() { fi msgtest 'Check if the right pdiff merger was used' - if grep -q '^pkgAcqIndexMergeDiffs::Done(): rred' $OUTPUT; then + if grep -q '^pkgAcqIndexMergeDiffs::Done(): rred' rootdir/tmp/testsuccess.output; then if echo "$*" | grep -q -- '-o Acquire::PDiffs::Merge=1'; then msgpass else @@ -96,6 +87,8 @@ SHA256-Patches: msgmsg "Testcase: index is already up-to-date: $*" find rootdir/var/lib/apt/lists -name '*diff_Index' -type f -delete testsuccess aptget update "$@" + testequal 'Hit http://localhost:8080 InRelease +Reading package lists...' aptget update "$@" -o Debug::Acquire::Transaction=0 -o Debug::pkgAcquire::Diffs=0 testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt newstuff diff --git a/test/interactive-helper/aptwebserver.cc b/test/interactive-helper/aptwebserver.cc index 86d5c06f0..6a411e24e 100644 --- a/test/interactive-helper/aptwebserver.cc +++ b/test/interactive-helper/aptwebserver.cc @@ -96,9 +96,12 @@ static void addFileHeaders(std::list &headers, FileFd &data)/*{{{*/ contentlength << "Content-Length: " << data.FileSize(); headers.push_back(contentlength.str()); } - std::string lastmodified("Last-Modified: "); - lastmodified.append(TimeRFC1123(data.ModificationTime())); - headers.push_back(lastmodified); + if (_config->FindB("aptwebserver::support::last-modified", true) == true) + { + std::string lastmodified("Last-Modified: "); + lastmodified.append(TimeRFC1123(data.ModificationTime())); + headers.push_back(lastmodified); + } } /*}}}*/ static void addDataHeaders(std::list &headers, std::string &data)/*{{{*/ -- cgit v1.2.3-70-g09d2 From 146f7715a9f36d246b461255b3c683b479296915 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 27 Apr 2015 10:59:27 +0200 Subject: improve partial/ cleanup in abort and failure cases Especially pdiff-enhanced downloads have the tendency to fail for various reasons from which we can recover and even a successful download used to leave the old unpatched index in partial/. By adding a new method responsible for making the transaction of an individual file happen we can at specialisations especially for abort cases to deal with the cleanup. This also helps in keeping the compressed indexes around if another index failed instead of keeping the decompressed files, which we wouldn't pick up in the next call. --- apt-pkg/acquire-item.cc | 193 +++++++++++++++++-------- apt-pkg/acquire-item.h | 17 ++- test/integration/framework | 6 +- test/integration/test-apt-update-expected-size | 2 +- test/integration/test-partial-file-support | 23 ++- test/integration/test-pdiff-usage | 2 +- 6 files changed, 161 insertions(+), 82 deletions(-) (limited to 'test/integration/framework') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 00862fe23..01ce0e650 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -173,6 +173,39 @@ void pkgAcquire::Item::Failed(string Message,pkgAcquire::MethodConfig *Cnf) ReportMirrorFailure(ErrorText); } /*}}}*/ +bool pkgAcquire::Item::TransactionState(TransactionStates const state) /*{{{*/ +{ + bool const Debug = _config->FindB("Debug::Acquire::Transaction", false); + switch(state) + { + case TransactionAbort: + if(Debug == true) + std::clog << " Cancel: " << DestFile << std::endl; + if (Status == pkgAcquire::Item::StatIdle) + { + Status = pkgAcquire::Item::StatDone; + Dequeue(); + } + break; + case TransactionCommit: + if(PartialFile != "") + { + if(Debug == true) + std::clog << "mv " << PartialFile << " -> "<< DestFile << " # " << DescURI() << std::endl; + + Rename(PartialFile, DestFile); + } else { + if(Debug == true) + std::clog << "rm " << DestFile << " # " << DescURI() << std::endl; + unlink(DestFile.c_str()); + } + // mark that this transaction is finished + TransactionManager = 0; + break; + } + return true; +} + /*}}}*/ // Acquire::Item::Start - Item has begun to download /*{{{*/ // --------------------------------------------------------------------- /* Stash status and the file size. Note that setting Complete means @@ -300,6 +333,9 @@ bool pkgAcquire::Item::RenameOnError(pkgAcquire::Item::RenameOnErrorState const // the method is expected to report a good error for this Status = StatError; break; + case PDiffError: + // no handling here, done by callers + break; } return false; } @@ -374,7 +410,7 @@ pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner, HashStringList const &ExpectedHashes, indexRecords *MetaIndexParser) : pkgAcqBaseIndex(Owner, TransactionManager, Target, ExpectedHashes, - MetaIndexParser), PackagesFileReadyInPartial(false) + MetaIndexParser) { Debug = _config->FindB("Debug::pkgAcquire::Diffs",false); @@ -671,20 +707,6 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ return false; } - // FIXME: make this use the method - PackagesFileReadyInPartial = true; - std::string const Partial = GetPartialFileNameFromURI(RealURI); - - FileFd From(CurrentPackagesFile, FileFd::ReadOnly); - FileFd To(Partial, FileFd::WriteEmpty); - if(CopyFile(From, To) == false) - return _error->Errno("CopyFile", "failed to copy"); - - if(Debug) - std::cerr << "Done copying " << CurrentPackagesFile - << " -> " << Partial - << std::endl; - // we have something, queue the diffs string::size_type const last_space = Description.rfind(" "); if(last_space != string::npos) @@ -738,6 +760,24 @@ void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig * Cnf)/*{{{ new pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser); } /*}}}*/ +bool pkgAcqDiffIndex::TransactionState(TransactionStates const state) /*{{{*/ +{ + if (pkgAcquire::Item::TransactionState(state) == false) + return false; + + switch (state) + { + case TransactionCommit: + break; + case TransactionAbort: + std::string const Partial = GetPartialFileNameFromURI(RealURI); + unlink(Partial.c_str()); + break; + } + + return true; +} + /*}}}*/ void pkgAcqDiffIndex::Done(string Message,unsigned long long Size,HashStringList const &Hashes, /*{{{*/ pkgAcquire::MethodConfig *Cnf) { @@ -765,15 +805,21 @@ void pkgAcqDiffIndex::Done(string Message,unsigned long long Size,HashStringList if(StringToBool(LookupTag(Message,"IMS-Hit"),false)) DestFile = FinalFile; - if(!ParseDiffIndex(DestFile)) - return Failed("Message: Couldn't parse pdiff index", Cnf); + if(ParseDiffIndex(DestFile) == false) + { + Failed("Message: Couldn't parse pdiff index", Cnf); + // queue for final move - this should happen even if we fail + // while parsing (e.g. on sizelimit) and download the complete file. + TransactionManager->TransactionStageCopy(this, DestFile, FinalFile); + return; + } - // queue for final move TransactionManager->TransactionStageCopy(this, DestFile, FinalFile); Complete = true; Status = StatDone; Dequeue(); + return; } /*}}}*/ @@ -808,6 +854,17 @@ pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner, } else { + // patching needs to be bootstrapped with the 'old' version + std::string const PartialFile = GetPartialFileNameFromURI(RealURI); + if (RealFileExists(PartialFile) == false) + { + if (symlink(GetFinalFilename().c_str(), PartialFile.c_str()) != 0) + { + Failed("Link creation of " + PartialFile + " to " + GetFinalFilename() + " failed", NULL); + return; + } + } + // get the next diff State = StateFetchDiff; QueueNextDiff(); @@ -822,6 +879,8 @@ void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig * Cnf)/*{{ if(Debug) std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << " with " << Message << std::endl << "Falling back to normal index file acquire" << std::endl; + DestFile = GetPartialFileNameFromURI(Target->URI); + RenameOnError(PDiffError); new pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser); Finish(); } @@ -950,6 +1009,8 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long long Size, HashStringLi if (fd.Size() != available_patches[0].patch_size || available_patches[0].patch_hashes != LocalHashes) { + // patchfiles are dated, so bad indicates a bad download, so kill it + unlink(DestFile.c_str()); Failed("Patch has Size/Hashsum mismatch", NULL); return; } @@ -1046,6 +1107,8 @@ void pkgAcqIndexMergeDiffs::Failed(string Message,pkgAcquire::MethodConfig * Cnf State = StateErrorDiff; if (Debug) std::clog << "Falling back to normal index file acquire" << std::endl; + DestFile = GetPartialFileNameFromURI(Target->URI); + RenameOnError(PDiffError); new pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser); } /*}}}*/ @@ -1069,6 +1132,8 @@ void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,HashStri if (fd.Size() != patch.patch_size || patch.patch_hashes != LocalHashes) { + // patchfiles are dated, so bad indicates a bad download, so kill it + unlink(DestFile.c_str()); Failed("Patch has Size/Hashsum mismatch", NULL); return; } @@ -1090,6 +1155,13 @@ void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,HashStri // this is the last completed diff, so we are ready to apply now State = StateApplyDiff; + // patching needs to be bootstrapped with the 'old' version + if (symlink(GetFinalFilename().c_str(), FinalFile.c_str()) != 0) + { + Failed("Link creation of " + FinalFile + " to " + GetFinalFilename() + " failed", NULL); + return; + } + if(Debug) std::clog << "Sending to rred method: " << FinalFile << std::endl; @@ -1109,15 +1181,14 @@ void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,HashStri return; } - // move the result into place - std::string const FinalFile = GetFinalFilename(); + std::string const Final = GetFinalFilename(); if(Debug) std::clog << "Queue patched file in place: " << std::endl - << DestFile << " -> " << FinalFile << std::endl; + << DestFile << " -> " << Final << std::endl; // queue for copy by the transaction manager - TransactionManager->TransactionStageCopy(this, DestFile, FinalFile); + TransactionManager->TransactionStageCopy(this, DestFile, Final); // ensure the ed's are gone regardless of list-cleanup for (std::vector::const_iterator I = allPatches->begin(); @@ -1127,6 +1198,7 @@ void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,HashStri std::string patch = PartialFile + ".ed." + (*I)->patch.file + ".gz"; unlink(patch.c_str()); } + unlink(FinalFile.c_str()); // all set and done Complete = true; @@ -1337,12 +1409,6 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) return; } - // on decompression failure, remove bad versions in partial/ - if (Stage == STAGE_DECOMPRESS_AND_VERIFY) - { - unlink(EraseFileName.c_str()); - } - Item::Failed(Message,Cnf); if(Target->IsOptional() && ExpectedHashes.empty() && Stage == STAGE_DOWNLOAD) @@ -1351,6 +1417,30 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) TransactionManager->AbortTransaction(); } /*}}}*/ +bool pkgAcqIndex::TransactionState(TransactionStates const state) /*{{{*/ +{ + if (pkgAcquire::Item::TransactionState(state) == false) + return false; + + switch (state) + { + case TransactionAbort: + if (Stage == STAGE_DECOMPRESS_AND_VERIFY) + { + // keep the compressed file, but drop the decompressed + EraseFileName.clear(); + if (PartialFile.empty() == false && flExtension(PartialFile) == "decomp") + unlink(PartialFile.c_str()); + } + break; + case TransactionCommit: + if (EraseFileName.empty() == false) + unlink(EraseFileName.c_str()); + break; + } + return true; +} + /*}}}*/ // pkgAcqIndex::GetFinalFilename - Return the full final file path /*{{{*/ std::string pkgAcqIndex::GetFinalFilename() const { @@ -1530,9 +1620,6 @@ void pkgAcqIndex::StageDecompressDone(string Message, return; } - // remove the compressed version of the file - unlink(EraseFileName.c_str()); - // Done, queue for rename on transaction finished TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename()); @@ -1568,14 +1655,7 @@ void pkgAcqMetaBase::AbortTransaction() for (std::vector::iterator I = Transaction.begin(); I != Transaction.end(); ++I) { - if(_config->FindB("Debug::Acquire::Transaction", false) == true) - std::clog << " Cancel: " << (*I)->DestFile << std::endl; - // the transaction will abort, so stop anything that is idle - if ((*I)->Status == pkgAcquire::Item::StatIdle) - { - (*I)->Status = pkgAcquire::Item::StatDone; - (*I)->Dequeue(); - } + (*I)->TransactionState(TransactionAbort); } Transaction.clear(); } @@ -1585,10 +1665,16 @@ bool pkgAcqMetaBase::TransactionHasError() { for (pkgAcquire::ItemIterator I = Transaction.begin(); I != Transaction.end(); ++I) - if((*I)->Status != pkgAcquire::Item::StatDone && - (*I)->Status != pkgAcquire::Item::StatIdle) - return true; - + { + switch((*I)->Status) { + case StatDone: break; + case StatIdle: break; + case StatAuthError: return true; + case StatError: return true; + case StatTransientNetworkError: return true; + case StatFetching: break; + } + } return false; } /*}}}*/ @@ -1603,24 +1689,7 @@ void pkgAcqMetaBase::CommitTransaction() for (std::vector::iterator I = Transaction.begin(); I != Transaction.end(); ++I) { - if((*I)->PartialFile != "") - { - if(_config->FindB("Debug::Acquire::Transaction", false) == true) - std::clog << "mv " << (*I)->PartialFile << " -> "<< (*I)->DestFile << " " - << (*I)->DescURI() << std::endl; - - Rename((*I)->PartialFile, (*I)->DestFile); - } else { - if(_config->FindB("Debug::Acquire::Transaction", false) == true) - std::clog << "rm " - << (*I)->DestFile - << " " - << (*I)->DescURI() - << std::endl; - unlink((*I)->DestFile.c_str()); - } - // mark that this transaction is finished - (*I)->TransactionManager = 0; + (*I)->TransactionState(TransactionCommit); } Transaction.clear(); } @@ -1634,7 +1703,7 @@ void pkgAcqMetaBase::TransactionStageCopy(Item *I, I->DestFile = To; } /*}}}*/ -// AcqMetaBase::TransactionStageRemoval - Sage a file for removal /*{{{*/ +// AcqMetaBase::TransactionStageRemoval - Stage a file for removal /*{{{*/ void pkgAcqMetaBase::TransactionStageRemoval(Item *I, const std::string &FinalFile) { diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index 148728b3c..33a28671c 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -344,7 +344,8 @@ class pkgAcquire::Item : public WeakPointable InvalidFormat, SignatureError, NotClearsigned, - MaximumSizeExceeded + MaximumSizeExceeded, + PDiffError, }; /** \brief Rename failed file and set error @@ -353,6 +354,12 @@ class pkgAcquire::Item : public WeakPointable */ bool RenameOnError(RenameOnErrorState const state); + enum TransactionStates { + TransactionCommit, + TransactionAbort, + }; + virtual bool TransactionState(TransactionStates const state); + /** \brief The HashSums of the item is supposed to have than done */ HashStringList ExpectedHashes; @@ -685,14 +692,12 @@ class APT_HIDDEN pkgAcqDiffIndex : public pkgAcqBaseIndex */ std::string Description; - /** \brief If the copy step of the packages file is done - */ - bool PackagesFileReadyInPartial; - /** \brief Get the full pathname of the final file for the current URI */ virtual std::string GetFinalFilename() const; virtual bool QueueURI(pkgAcquire::ItemDesc &Item); + + virtual bool TransactionState(TransactionStates const state); public: // Specialized action members virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf); @@ -1010,6 +1015,8 @@ class APT_HIDDEN pkgAcqIndex : public pkgAcqBaseIndex /** \brief Get the full pathname of the final file for the current URI */ virtual std::string GetFinalFilename() const; + virtual bool TransactionState(TransactionStates const state); + public: // Specialized action members virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf); diff --git a/test/integration/framework b/test/integration/framework index 4229ae162..7564a0faf 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1523,9 +1523,13 @@ aptautotest_aptget_update() { testfilestats "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:755" testfilestats "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:755" # all copied files are properly chmodded - for file in $(find "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" -maxdepth 1 -type f ! -name 'lock'); do + for file in $(find "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" -type f ! -name 'lock'); do testfilestats "$file" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644" done + if [ "$1" = 'testsuccess' ]; then + # 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 } aptautotest_apt_update() { aptautotest_aptget_update "$@"; } aptautotest_aptcdrom_add() { aptautotest_aptget_update "$@"; } diff --git a/test/integration/test-apt-update-expected-size b/test/integration/test-apt-update-expected-size index 9f58308aa..7efccaa57 100755 --- a/test/integration/test-apt-update-expected-size +++ b/test/integration/test-apt-update-expected-size @@ -34,7 +34,7 @@ test_packagestoobig() { done NEW_SIZE="$(stat --printf=%s aptarchive/dists/unstable/main/binary-i386/Packages)" testfailuremsg "W: Failed to fetch ${1}/dists/unstable/main/binary-i386/Packages Writing more data than expected ($NEW_SIZE > $SIZE) -E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -o Debug::pkgAcquire::Worker=0 +E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -o Debug::pkgAcquire::Worker=0 -o Debug::Acquire::Transaction=0 } methodtest() { diff --git a/test/integration/test-partial-file-support b/test/integration/test-partial-file-support index b6b305d25..85046b3eb 100755 --- a/test/integration/test-partial-file-support +++ b/test/integration/test-partial-file-support @@ -126,18 +126,17 @@ testrun() { testwebserverlaststatuscode '200' "$DOWNLOADLOG" } -msgmsg 'http: Test with Content-Length' -webserverconfig 'aptwebserver::chunked-transfer-encoding' 'false' -testrun 'http://localhost:8080' -msgmsg 'http: Test with Transfer-Encoding: chunked' -webserverconfig 'aptwebserver::chunked-transfer-encoding' 'true' -testrun 'http://localhost:8080' +serverconfigs() { + msgmsg "${1%%:*}: Test with Content-Length" + webserverconfig 'aptwebserver::chunked-transfer-encoding' 'false' + testrun "$1" + msgmsg "${1%%:*}: Test with Transfer-Encoding: chunked" + webserverconfig 'aptwebserver::chunked-transfer-encoding' 'true' + testrun "$1" +} + +serverconfigs 'http://localhost:8080' changetohttpswebserver -msgmsg 'https: Test with Content-Length' -webserverconfig 'aptwebserver::chunked-transfer-encoding' 'false' -testrun 'https://localhost:4433' -msgmsg 'https: Test with Transfer-Encoding: chunked' -webserverconfig 'aptwebserver::chunked-transfer-encoding' 'true' -testrun 'https://localhost:4433' +serverconfigs 'https://localhost:4433' diff --git a/test/integration/test-pdiff-usage b/test/integration/test-pdiff-usage index 5e759e50e..7d72a6944 100755 --- a/test/integration/test-pdiff-usage +++ b/test/integration/test-pdiff-usage @@ -47,7 +47,7 @@ testrun() { compressfile 'aptarchive/Packages' generatereleasefiles signreleasefiles - rm -rf aptarchive/Packages.diff rootdir/var/lib/apt/lists + rm -rf aptarchive/Packages.diff rootdir/var/lib/apt/lists rootdir/var/lib/apt/lists-bak testsuccess aptget update "$@" cp -a rootdir/var/lib/apt/lists rootdir/var/lib/apt/lists-bak testnopackage newstuff -- cgit v1.2.3-70-g09d2 From e8fb1cdfdd13e45f2b3abbd57a28b57ae6137f14 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 9 May 2015 18:55:41 +0200 Subject: sync TFRewrite*Order arrays with dpkg and dak dpkg and dak know various field names and order them in their output, while we have yet another order and have to play catch up with them as we are sitting between chairs here and neither order is ideal for us, too. A little testcase is from now on supposed to help ensureing that we do not derivate to far away from which fields dpkg knows and orders. --- apt-pkg/tagfile-order.c | 109 +++++++++++++++++++++ apt-pkg/tagfile.cc | 63 +----------- debian/tests/run-tests | 1 + test/integration/framework | 1 + test/integration/test-apt-ftparchive-cachedb | 6 +- .../test-apt-ftparchive-cachedb-lp1274466 | 6 +- test/integration/test-apt-ftparchive-src-cachedb | 18 ++-- test/integration/test-apt-tagfile-fields-order | 82 ++++++++++++++++ 8 files changed, 211 insertions(+), 75 deletions(-) create mode 100644 apt-pkg/tagfile-order.c create mode 100755 test/integration/test-apt-tagfile-fields-order (limited to 'test/integration/framework') diff --git a/apt-pkg/tagfile-order.c b/apt-pkg/tagfile-order.c new file mode 100644 index 000000000..10c61ab94 --- /dev/null +++ b/apt-pkg/tagfile-order.c @@ -0,0 +1,109 @@ +/* In this file is the order defined in which e.g. apt-ftparchive will write stanzas in. + Other commands might or might not use this. 'apt-cache show' e.g. does NOT! + + The order we chose here is inspired by both dpkg and dak. + The testcase test/integration/test-apt-tagfile-fields-order intends to ensure that + this file isn't lacking (too far) behind dpkg over time. */ + +static const char *iTFRewritePackageOrder[] = { + "Package", + "Package-Type", + "Architecture", + "Subarchitecture", // Used only by d-i + "Version", + "Revision", // Obsolete (warning in dpkg) + "Package-Revision", // Obsolete (warning in dpkg) + "Package_Revision", // Obsolete (warning in dpkg) + "Kernel-Version", // Used only by d-i + "Built-Using", + "Built-For-Profiles", + "Multi-Arch", + "Status", + "Priority", + "Class", // dpkg nickname for Priority + "Essential", + "Installer-Menu-Item", // Used only by d-i + "Section", + "Source", + "Origin", + "Maintainer", + "Original-Maintainer", // unknown in dpkg order + "Bugs", + "Config-Version", // Internal of dpkg + "Conffiles", + "Triggers-Awaited", + "Triggers-Pending", + "Installed-Size", + "Provides", + "Pre-Depends", + "Depends", + "Recommends", + "Recommended", // dpkg nickname for Recommends + "Suggests", + "Optional", // dpkg nickname for Suggests + "Conflicts", + "Breaks", + "Replaces", + "Enhances", + "Filename", + "MSDOS-Filename", // Obsolete (used by dselect) + "Size", + "MD5sum", + "SHA1", + "SHA256", + "SHA512", + "Homepage", + "Description", + "Tag", + "Task", + 0 +}; +static const char *iTFRewriteSourceOrder[] = { + "Package", + "Source", // dsc file, renamed to Package in Sources + "Format", + "Binary", + "Architecture", + "Version", + "Priority", + "Class", // dpkg nickname for Priority + "Section", + "Origin", + "Maintainer", + "Original-Maintainer", // unknown in dpkg order + "Uploaders", + "Dm-Upload-Allowed", // Obsolete (ignored by dak) + "Standards-Version", + "Build-Depends", + "Build-Depends-Arch", + "Build-Depends-Indep", + "Build-Conflicts", + "Build-Conflicts-Arch", + "Build-Conflicts-Indep", + "Testsuite", + "Homepage", + "Vcs-Browser", + "Vcs-Browse", // dak only (nickname?) + "Vcs-Arch", + "Vcs-Bzr", + "Vcs-Cvs", + "Vcs-Darcs", + "Vcs-Git", + "Vcs-Hg", + "Vcs-Mtn", + "Vcs-Svn", + "Directory", + "Package-List", + "Files", + "Checksums-Md5", + "Checksums-Sha1", + "Checksums-Sha256", + "Checksums-Sha512", + 0 +}; + +/* Two levels of initialization are used because gcc will set the symbol + size of an array to the length of the array, causing dynamic relinking + errors. Doing this makes the symbol size constant */ +const char **TFRewritePackageOrder = iTFRewritePackageOrder; +const char **TFRewriteSourceOrder = iTFRewriteSourceOrder; diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 9c40c8c92..2f7900d93 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -623,71 +623,14 @@ APT_PURE unsigned int pkgTagSection::Count() const { /*{{{*/ return d->Tags.size() - 1; } /*}}}*/ + +#include "tagfile-order.c" + // TFRewrite - Rewrite a control record /*{{{*/ // --------------------------------------------------------------------- /* This writes the control record to stdout rewriting it as necessary. The override map item specificies the rewriting rules to follow. This also takes the time to sort the feild list. */ - -/* The order of this list is taken from dpkg source lib/parse.c the fieldinfos - array. */ -static const char *iTFRewritePackageOrder[] = { - "Package", - "Essential", - "Status", - "Priority", - "Section", - "Installed-Size", - "Maintainer", - "Original-Maintainer", - "Architecture", - "Source", - "Version", - "Revision", // Obsolete - "Config-Version", // Obsolete - "Replaces", - "Provides", - "Depends", - "Pre-Depends", - "Recommends", - "Suggests", - "Conflicts", - "Breaks", - "Conffiles", - "Filename", - "Size", - "MD5sum", - "SHA1", - "SHA256", - "SHA512", - "MSDOS-Filename", // Obsolete - "Description", - 0}; -static const char *iTFRewriteSourceOrder[] = {"Package", - "Source", - "Binary", - "Version", - "Priority", - "Section", - "Maintainer", - "Original-Maintainer", - "Build-Depends", - "Build-Depends-Indep", - "Build-Conflicts", - "Build-Conflicts-Indep", - "Architecture", - "Standards-Version", - "Format", - "Directory", - "Files", - 0}; - -/* Two levels of initialization are used because gcc will set the symbol - size of an array to the length of the array, causing dynamic relinking - errors. Doing this makes the symbol size constant */ -const char **TFRewritePackageOrder = iTFRewritePackageOrder; -const char **TFRewriteSourceOrder = iTFRewriteSourceOrder; - bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[], TFRewriteData *Rewrite) { diff --git a/debian/tests/run-tests b/debian/tests/run-tests index 7cc37f618..e459d7093 100644 --- a/debian/tests/run-tests +++ b/debian/tests/run-tests @@ -11,6 +11,7 @@ make -C test/interactive-helper/ # run tests against the installed apt, use "env -i" to ensure # the host env does not pollute our environment env -i \ +APT_INTEGRATION_TESTS_SOURCE_DIR=$(pwd) \ APT_INTEGRATION_TESTS_WEBSERVER_BIN_DIR=$(pwd)/build/bin \ APT_INTEGRATION_TESTS_METHODS_DIR=/usr/lib/apt/methods \ APT_INTEGRATION_TESTS_LIBEXEC_DIR=/usr/lib/apt/ \ diff --git a/test/integration/framework b/test/integration/framework index 7564a0faf..03c188189 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -189,6 +189,7 @@ setupenvironment() { TESTDIRECTORY=$(readlink -f $(dirname $0)) # 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"} diff --git a/test/integration/test-apt-ftparchive-cachedb b/test/integration/test-apt-ftparchive-cachedb index 3454ee36a..962095320 100755 --- a/test/integration/test-apt-ftparchive-cachedb +++ b/test/integration/test-apt-ftparchive-cachedb @@ -3,12 +3,12 @@ set -e ensure_correct_packages_file() { testequal "Package: foo +Architecture: i386 +Version: 1 Priority: optional Section: others -$(dpkg-deb -I ./aptarchive/pool/main/foo_1_i386.deb | grep 'Installed-Size:' | sed 's#^ ##') Maintainer: Joe Sixpack -Architecture: i386 -Version: 1 +$(dpkg-deb -I ./aptarchive/pool/main/foo_1_i386.deb | grep 'Installed-Size:' | sed 's#^ ##') Filename: pool/main/foo_1_i386.deb" head -n8 ./aptarchive/dists/test/main/binary-i386/Packages } diff --git a/test/integration/test-apt-ftparchive-cachedb-lp1274466 b/test/integration/test-apt-ftparchive-cachedb-lp1274466 index 1f86e367f..8b768441a 100755 --- a/test/integration/test-apt-ftparchive-cachedb-lp1274466 +++ b/test/integration/test-apt-ftparchive-cachedb-lp1274466 @@ -27,12 +27,12 @@ testfailure grep 7da58ff901a40ecf42a730dc33198b182e9ba9ec98799fc2c2b6fabeeee40cc # regression test for corruption with previous generation of cachedb testsuccessequal "Package: foo +Architecture: i386 +Version: 1 Priority: optional Section: others -Installed-Size: 29 Maintainer: Joe Sixpack -Architecture: i386 -Version: 1 +Installed-Size: 29 Filename: ./foo_1_i386.deb Size: 1270 MD5sum: 85d0e908c1a897700e2c5dea72d7e3c0 diff --git a/test/integration/test-apt-ftparchive-src-cachedb b/test/integration/test-apt-ftparchive-src-cachedb index 2a361ecc0..66a3b7845 100755 --- a/test/integration/test-apt-ftparchive-src-cachedb +++ b/test/integration/test-apt-ftparchive-src-cachedb @@ -3,16 +3,16 @@ set -e assert_correct_sources_file() { testsuccessequal "Package: bar +Format: 3.0 (native) +Binary: bar Architecture: all Version: 1.0 -Binary: bar -Format: 3.0 (native) Directory: pool/main +Package-List: + bar deb admin extra Files: 7b57dd065e51de5905288a5104d4bef5 406 bar_1.0.dsc d41d8cd98f00b204e9800998ecf8427e 0 bar_1.0.tar.gz -Package-List: - bar deb admin extra Checksums-Sha1: 17a40b76715f393ab7fd6485c9392a02f1adf903 406 bar_1.0.dsc da39a3ee5e6b4b0d3255bfef95601890afd80709 0 bar_1.0.tar.gz @@ -24,16 +24,16 @@ Checksums-Sha512: cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e 0 bar_1.0.tar.gz Package: foo +Format: 3.0 (native) +Binary: foo Architecture: all Version: 1.0 -Binary: foo -Format: 3.0 (native) Directory: pool/main +Package-List: + foo deb admin extra Files: d144826e6f02831c1933e910c92cd7e0 171 foo_1.0.dsc d41d8cd98f00b204e9800998ecf8427e 0 foo_1.0.tar.gz -Package-List: - foo deb admin extra Checksums-Sha1: 979306aa3ccff3d61bba062bb6977e2493c6f907 171 foo_1.0.dsc da39a3ee5e6b4b0d3255bfef95601890afd80709 0 foo_1.0.tar.gz @@ -43,7 +43,7 @@ Checksums-Sha256: Checksums-Sha512: 3da0240fd764657c2f3661b4d750578a9a99b0580591b133756379d48117ebda87a5ed2467f513200d6e7eaf51422cbe91c15720eef7fb4bba2cc8ff81ebc547 171 foo_1.0.dsc cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e 0 foo_1.0.tar.gz -" aptsortpkgs ./aptarchive/dists/test/main/source/Sources +" aptsortpkgs ./aptarchive/dists/test/main/source/Sources -o APT::SortPkgs::Source=true } create_source_files() { diff --git a/test/integration/test-apt-tagfile-fields-order b/test/integration/test-apt-tagfile-fields-order new file mode 100755 index 000000000..27d5c14ff --- /dev/null +++ b/test/integration/test-apt-tagfile-fields-order @@ -0,0 +1,82 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework +setupenvironment + +dpkg_field_ordered_list() { + local FIELDS="$(perl -e " +use Dpkg::Control; +use Dpkg::Control::Fields; +foreach \$f (field_ordered_list(${1})) { + print \"\$f\\n\"; +}" | sort -u)" + if [ -z "$FIELDS" ]; then + msgfail 'Could not get fields via libdpkg-perl' + fi + echo "$FIELDS" +} + +comparelsts() { + local DIFFOUTPUT="$(diff -u apt.lst dpkg.lst || true)" + if echo "$DIFFOUTPUT" | grep -q '^+[^+]'; then + echo + echo "$DIFFOUTPUT" | grep '^[+-][^+-]' + msgfail + else + msgpass + fi +} + +msgtest 'Check that apt knows all fields dpkg orders in' 'Packages' +dpkg_field_ordered_list 'CTRL_INDEX_PKG' > dpkg.lst +sed -ne 's#^ "\(.*\)",.*$#\1#p' ${SOURCEDIRECTORY}/apt-pkg/tagfile-order.c | sed -n '/^Package$/,/^Package$/ p' | head -n -1 | sort -u > apt.lst +comparelsts + +msgtest 'Check that apt knows all fields dpkg orders in' 'status' +dpkg_field_ordered_list 'CTRL_FILE_STATUS' > dpkg.lst +comparelsts + +msgtest 'Check that apt knows all fields dpkg orders in' 'DEBIAN/control' +dpkg_field_ordered_list 'CTRL_PKG_DEB' > dpkg.lst +comparelsts + +msgtest 'Check that apt knows all fields dpkg orders in' 'Sources' +dpkg_field_ordered_list 'CTRL_INDEX_SRC' > dpkg.lst +echo 'Package' > apt.tmp +sed -ne 's#^ "\(.*\)",.*$#\1#p' ${SOURCEDIRECTORY}/apt-pkg/tagfile-order.c | sed '/^Package$/,/^Package$/ d' >> apt.tmp +sort -u apt.tmp > apt.lst +comparelsts + +msgtest 'Check that apt knows all fields dpkg orders in' 'dsc' +dpkg_field_ordered_list 'CTRL_PKG_SRC' > dpkg.lst +comparelsts + +# HACK, but there is no good way to acquire sources in tests and/or to remember to run this regular manually +if [ "$USER" = 'david' ]; then + msgtest 'Check if we have somewhere the sources of' 'dpkg' + DPKGSOURCE="$(locate dpkg/lib/dpkg/parse.c | head -n 1 || true)" + if [ -z "$DPKGSOURCE" ]; then + msgskip 'Not found' + else + msgpass + msgtest 'Check that apt knows about all fields' 'dpkg parses' + sed -n 's#^.*FIELD("\(.*\)").*$#\1#p' "${DPKGSOURCE}" | sort -u > dpkg.lst + sed -ne 's#^ "\(.*\)",.*$#\1#p' ${SOURCEDIRECTORY}/apt-pkg/tagfile-order.c | sed -n '/^Package$/,/^Package$/ p' | head -n -1 | sort -u > apt.lst + comparelsts + fi + + msgtest 'Check if we have somewhere the sources of' 'dak' + DAKSOURCE="$(locate dak/setup/core-init.d/080_metadatakeys | head -n 1 || true)" + if [ -z "$DAKSOURCE" ]; then + msgskip 'Not found' + else + msgpass + msgtest 'Check that apt knows about all fields' 'dak knows' + # dak mixes both, so we can only check with the mixed one as well + sed -ne "s#^.* VALUES ('\(.*\)', \(.*\)).*\$#\1 \2#p" "${DAKSOURCE}" | cut -d ' ' -f 1 | sort -u > dpkg.lst + sed -ne 's#^ "\(.*\)",.*$#\1#p' ${SOURCEDIRECTORY}/apt-pkg/tagfile-order.c | sort -u > apt.lst + comparelsts + fi +fi -- cgit v1.2.3-70-g09d2 From dcbb364fc69e1108b3fea3adb12a7ba83d9af467 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 12 May 2015 00:30:16 +0200 Subject: detect 416 complete file in partial by expected hash If we have the expected hashes we can check with them if the file we have in partial we got a 416 for is the expected file. We detected this with same-size before, but not every server sends a good Content-Range header with a 416 response. --- methods/https.cc | 37 +++++++++++++++++++++------ methods/https.h | 1 + methods/server.cc | 19 +++++++++++--- test/integration/framework | 2 +- test/integration/test-apt-update-transactions | 1 + test/integration/test-partial-file-support | 10 ++++++-- test/interactive-helper/aptwebserver.cc | 9 ++++--- 7 files changed, 62 insertions(+), 17 deletions(-) (limited to 'test/integration/framework') diff --git a/methods/https.cc b/methods/https.cc index c6b75d9ad..712e9ee73 100644 --- a/methods/https.cc +++ b/methods/https.cc @@ -40,7 +40,9 @@ using namespace std; struct APT_HIDDEN CURLUserPointer { HttpsMethod * const https; HttpsMethod::FetchResult * const Res; - CURLUserPointer(HttpsMethod * const https, HttpsMethod::FetchResult * const Res) : https(https), Res(Res) {} + HttpsMethod::FetchItem const * const Itm; + CURLUserPointer(HttpsMethod * const https, HttpsMethod::FetchResult * const Res, + HttpsMethod::FetchItem const * const Itm) : https(https), Res(Res), Itm(Itm) {} }; size_t @@ -61,13 +63,32 @@ HttpsMethod::parse_header(void *buffer, size_t size, size_t nmemb, void *userp) { if (me->https->Server->Result != 416 && me->https->Server->StartPos != 0) ; - else if (me->https->Server->Result == 416 && me->https->Server->Size == me->https->File->FileSize()) + else if (me->https->Server->Result == 416) { - me->https->Server->Result = 200; - me->https->Server->StartPos = me->https->Server->Size; - // the actual size is not important for https as curl will deal with it - // by itself and e.g. doesn't bother us with transport-encoding… - me->https->Server->JunkSize = std::numeric_limits::max(); + bool partialHit = false; + if (me->Itm->ExpectedHashes.usable() == true) + { + Hashes resultHashes(me->Itm->ExpectedHashes); + FileFd file(me->Itm->DestFile, FileFd::ReadOnly); + me->https->Server->Size = file.FileSize(); + me->https->Server->Date = file.ModificationTime(); + resultHashes.AddFD(file); + HashStringList const hashList = resultHashes.GetHashStringList(); + partialHit = (me->Itm->ExpectedHashes == hashList); + } + else if (me->https->Server->Result == 416 && me->https->Server->Size == me->https->File->FileSize()) + partialHit = true; + + if (partialHit == true) + { + me->https->Server->Result = 200; + me->https->Server->StartPos = me->https->Server->Size; + // the actual size is not important for https as curl will deal with it + // by itself and e.g. doesn't bother us with transport-encoding… + me->https->Server->JunkSize = std::numeric_limits::max(); + } + else + me->https->Server->StartPos = 0; } else me->https->Server->StartPos = 0; @@ -221,7 +242,7 @@ bool HttpsMethod::Fetch(FetchItem *Itm) maybe_add_auth (Uri, _config->FindFile("Dir::Etc::netrc")); FetchResult Res; - CURLUserPointer userp(this, &Res); + CURLUserPointer userp(this, &Res, Itm); // callbacks curl_easy_setopt(curl, CURLOPT_URL, static_cast(Uri).c_str()); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, parse_header); diff --git a/methods/https.h b/methods/https.h index 6e32e8d3d..57fc292ee 100644 --- a/methods/https.h +++ b/methods/https.h @@ -79,6 +79,7 @@ class HttpsMethod : public ServerMethod virtual bool Configuration(std::string Message); virtual ServerState * CreateServerState(URI uri); using pkgAcqMethod::FetchResult; + using pkgAcqMethod::FetchItem; HttpsMethod() : ServerMethod("1.2",Pipeline | SendConfig), File(NULL) { diff --git a/methods/server.cc b/methods/server.cc index 2116926b0..bd01c3e98 100644 --- a/methods/server.cc +++ b/methods/server.cc @@ -269,7 +269,7 @@ ServerMethod::DealWithHeaders(FetchResult &Res) Res.LastModified = Queue->LastModified; return IMS_HIT; } - + /* Redirect * * Note that it is only OK for us to treat all redirection the same @@ -314,7 +314,20 @@ ServerMethod::DealWithHeaders(FetchResult &Res) struct stat SBuf; if (stat(Queue->DestFile.c_str(),&SBuf) >= 0 && SBuf.st_size > 0) { - if ((unsigned long long)SBuf.st_size == Server->Size) + bool partialHit = false; + if (Queue->ExpectedHashes.usable() == true) + { + Hashes resultHashes(Queue->ExpectedHashes); + FileFd file(Queue->DestFile, FileFd::ReadOnly); + Server->Size = file.FileSize(); + Server->Date = file.ModificationTime(); + resultHashes.AddFD(file); + HashStringList const hashList = resultHashes.GetHashStringList(); + partialHit = (Queue->ExpectedHashes == hashList); + } + else if ((unsigned long long)SBuf.st_size == Server->Size) + partialHit = true; + if (partialHit == true) { // the file is completely downloaded, but was not moved if (Server->HaveContent == true) @@ -351,7 +364,7 @@ ServerMethod::DealWithHeaders(FetchResult &Res) // This is some sort of 2xx 'data follows' reply Res.LastModified = Server->Date; Res.Size = Server->Size; - + // Open the file delete File; File = new FileFd(Queue->DestFile,FileFd::WriteAny); diff --git a/test/integration/framework b/test/integration/framework index 03c188189..2a53e8365 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1128,7 +1128,7 @@ acquire::cdrom::autodetect 0;" > rootdir/etc/apt/apt.conf.d/00cdrom downloadfile() { local PROTO="${1%%:*}" if ! apthelper -o Debug::Acquire::${PROTO}=1 -o Debug::pkgAcquire::Worker=1 \ - download-file "$1" "$2" 2>&1 ; then + download-file "$1" "$2" "$3" 2>&1 ; then return 1 fi # only if the file exists the download was successful diff --git a/test/integration/test-apt-update-transactions b/test/integration/test-apt-update-transactions index f028ac0c7..67dd633f9 100755 --- a/test/integration/test-apt-update-transactions +++ b/test/integration/test-apt-update-transactions @@ -63,6 +63,7 @@ testsetup 'file' changetowebserver webserverconfig 'aptwebserver::support::modified-since' 'false' "$1" webserverconfig 'aptwebserver::support::last-modified' 'false' "$1" # curl is clever and sees hits here also +webserverconfig 'aptwebserver::support::range' 'false' "$1" testsetup 'http' diff --git a/test/integration/test-partial-file-support b/test/integration/test-partial-file-support index 85046b3eb..c07af7bd0 100755 --- a/test/integration/test-partial-file-support +++ b/test/integration/test-partial-file-support @@ -17,8 +17,8 @@ DOWNLOADLOG='rootdir/tmp/testdownloadfile.log' testdownloadfile() { rm -f "$DOWNLOADLOG" - msgtest "Testing download of file $2 with" "$1" - if ! downloadfile "$2" "$3" > "$DOWNLOADLOG"; then + msgtest "Testing download of file $2 with" "$1 $5" + if ! downloadfile "$2" "$3" "$5" > "$DOWNLOADLOG"; then cat >&2 "$DOWNLOADLOG" msgfail else @@ -78,6 +78,12 @@ followuprequest() { testdownloadfile 'completely downloaded file' "${1}/testfile" "$DOWN" '=' testwebserverlaststatuscode '416' "$DOWNLOADLOG" + webserverconfig 'aptwebserver::support::content-range' 'false' + copysource $TESTFILE 1M $DOWN + testdownloadfile 'completely downloaded file' "${1}/testfile" "$DOWN" '=' "SHA1:$(sha1sum "$TESTFILE" | cut -d' ' -f 1)" + testwebserverlaststatuscode '416' "$DOWNLOADLOG" + webserverconfig 'aptwebserver::support::content-range' 'true' + copysource $TESTFILE 1M $DOWN copysource "${TESTFILE}2" 20 "${DOWN}2" msgtest 'Testing download of files with' 'completely downloaded file + partial file' diff --git a/test/interactive-helper/aptwebserver.cc b/test/interactive-helper/aptwebserver.cc index 6a411e24e..c933060e7 100644 --- a/test/interactive-helper/aptwebserver.cc +++ b/test/interactive-helper/aptwebserver.cc @@ -745,9 +745,12 @@ static void * handleClient(void * voidclient) /*{{{*/ } else { - std::ostringstream contentrange; - contentrange << "Content-Range: bytes */" << filesize; - headers.push_back(contentrange.str()); + if (_config->FindB("aptwebserver::support::content-range", true) == true) + { + std::ostringstream contentrange; + contentrange << "Content-Range: bytes */" << filesize; + headers.push_back(contentrange.str()); + } sendError(client, 416, *m, sendContent, "", headers); break; } -- cgit v1.2.3-70-g09d2 From 8eafc759544298211cd0bfaa3919afc0fadd47d1 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 13 May 2015 16:09:12 +0200 Subject: detect Releasefile IMS hits even if the server doesn't Not all servers we are talking to support If-Modified-Since and some are not even sending Last-Modified for us, so in an effort to detect such hits we run a hashsum check on the 'old' compared to the 'new' file, we got the hashes for the 'new' already for "free" from the methods anyway and hence just need to calculated the old ones. This allows us to detect hits even with unsupported servers, which in turn means we benefit from all the new hit behavior also here. --- apt-pkg/acquire-item.cc | 31 ++++++++++---- apt-pkg/acquire-item.h | 2 +- apt-pkg/acquire-worker.cc | 8 ++-- methods/https.cc | 2 +- test/integration/framework | 9 ++++ test/integration/test-apt-update-expected-size | 1 + test/integration/test-apt-update-not-modified | 58 +++++++++++++++++++++++++- test/integration/test-apt-update-rollback | 1 + test/integration/test-apt-update-transactions | 2 + 9 files changed, 99 insertions(+), 15 deletions(-) (limited to 'test/integration/framework') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 1090912f5..78dace12c 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -253,7 +253,10 @@ bool pkgAcquire::Item::Rename(string From,string To) strprintf(S, _("rename failed, %s (%s -> %s)."), strerror(errno), From.c_str(),To.c_str()); Status = StatError; - ErrorText += S; + if (ErrorText.empty()) + ErrorText = S; + else + ErrorText = ErrorText + ": " + S; return false; } /*}}}*/ @@ -1794,7 +1797,7 @@ void pkgAcqMetaSig::Done(string Message,unsigned long long Size, if(AuthPass == false) { - if(CheckDownloadDone(Message) == true) + if(CheckDownloadDone(Message, Hashes) == true) { // destfile will be modified to point to MetaIndexFile for the // gpgv method, so we need to save it here @@ -1837,7 +1840,8 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/ Status = StatDone; } else { _error->Error("%s", downgrade_msg.c_str()); - Rename(MetaIndexFile, MetaIndexFile+".FAILED"); + if (TransactionManager->IMSHit == false) + Rename(MetaIndexFile, MetaIndexFile+".FAILED"); Item::Failed("Message: " + downgrade_msg, Cnf); TransactionManager->AbortTransaction(); return; @@ -1922,12 +1926,12 @@ void pkgAcqMetaIndex::Done(string Message,unsigned long long Size, /*{{{*/ { Item::Done(Message,Size,Hashes,Cfg); - if(CheckDownloadDone(Message)) + if(CheckDownloadDone(Message, Hashes)) { // we have a Release file, now download the Signature, all further // verify/queue for additional downloads will be done in the // pkgAcqMetaSig::Done() code - std::string MetaIndexFile = DestFile; + std::string const MetaIndexFile = DestFile; new pkgAcqMetaSig(Owner, TransactionManager, MetaIndexSigURI, MetaIndexSigURIDesc, MetaIndexSigShortDesc, MetaIndexFile, IndexTargets, @@ -2008,7 +2012,7 @@ void pkgAcqMetaBase::QueueForSignatureVerify(const std::string &MetaIndexFile, } /*}}}*/ // pkgAcqMetaBase::CheckDownloadDone /*{{{*/ -bool pkgAcqMetaBase::CheckDownloadDone(const std::string &Message) +bool pkgAcqMetaBase::CheckDownloadDone(const std::string &Message, HashStringList const &Hashes) { // We have just finished downloading a Release file (it is not // verified yet) @@ -2031,7 +2035,18 @@ bool pkgAcqMetaBase::CheckDownloadDone(const std::string &Message) // make sure to verify against the right file on I-M-S hit IMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false); - if(IMSHit) + if (IMSHit == false) + { + // detect IMS-Hits servers haven't detected by Hash comparison + std::string FinalFile = GetFinalFilename(); + if (RealFileExists(FinalFile) && Hashes.VerifyFile(FinalFile) == true) + { + IMSHit = true; + unlink(DestFile.c_str()); + } + } + + if(IMSHit == true) { // for simplicity, the transaction manager is always InRelease // even if it doesn't exist. @@ -2273,7 +2288,7 @@ void pkgAcqMetaClearSig::Done(std::string Message,unsigned long long Size, if(AuthPass == false) { - if(CheckDownloadDone(Message) == true) + if(CheckDownloadDone(Message, Hashes) == true) QueueForSignatureVerify(DestFile, DestFile); return; } diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index 33a28671c..646de8416 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -429,7 +429,7 @@ class pkgAcqMetaBase : public pkgAcquire::Item /*{{{*/ * \param Message The message block received from the fetch * subprocess. */ - bool CheckDownloadDone(const std::string &Message); + bool CheckDownloadDone(const std::string &Message, HashStringList const &Hashes); /** \brief Queue the downloaded Signature for verification */ void QueueForSignatureVerify(const std::string &MetaIndexFile, diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc index bee01e620..9254e20a3 100644 --- a/apt-pkg/acquire-worker.cc +++ b/apt-pkg/acquire-worker.cc @@ -333,13 +333,12 @@ bool pkgAcquire::Worker::RunMessages() // see if there is a hash to verify HashStringList ReceivedHashes; - HashStringList expectedHashes = Owner->HashSums(); - for (HashStringList::const_iterator hs = expectedHashes.begin(); hs != expectedHashes.end(); ++hs) + for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type) { - std::string const tagname = hs->HashType() + "-Hash"; + std::string const tagname = std::string(*type) + "-Hash"; std::string const hashsum = LookupTag(Message, tagname.c_str()); if (hashsum.empty() == false) - ReceivedHashes.push_back(HashString(hs->HashType(), hashsum)); + ReceivedHashes.push_back(HashString(*type, hashsum)); } if(_config->FindB("Debug::pkgAcquire::Auth", false) == true) @@ -349,6 +348,7 @@ bool pkgAcquire::Worker::RunMessages() for (HashStringList::const_iterator hs = ReceivedHashes.begin(); hs != ReceivedHashes.end(); ++hs) std::clog << "\t- " << hs->toStr() << std::endl; std::clog << "ExpectedHash:" << endl; + HashStringList expectedHashes = Owner->HashSums(); for (HashStringList::const_iterator hs = expectedHashes.begin(); hs != expectedHashes.end(); ++hs) std::clog << "\t- " << hs->toStr() << std::endl; std::clog << endl; diff --git a/methods/https.cc b/methods/https.cc index 712e9ee73..fa143439a 100644 --- a/methods/https.cc +++ b/methods/https.cc @@ -444,7 +444,7 @@ bool HttpsMethod::Fetch(FetchItem *Itm) char err[255]; snprintf(err, sizeof(err) - 1, "HttpError%i", Server->Result); SetFailReason(err); - _error->Error("%s", err); + _error->Error("%i %s", Server->Result, Server->Code); // unlink, no need keep 401/404 page content in partial/ unlink(File->Name().c_str()); return false; diff --git a/test/integration/framework b/test/integration/framework index 2a53e8365..8c8936ead 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1005,6 +1005,15 @@ signreleasefiles() { msgdone "info" } +redatereleasefiles() { + local DATE="$(date -d "$1" '+%a, %d %b %Y %H:%M:%S %Z')" + for release in $(find aptarchive/ -name 'Release'); do + sed -i "s/^Date: .*$/Date: ${DATE}/" $release + touch -d "$DATE" $release + done + signreleasefiles "${2:-Joe Sixpack}" +} + webserverconfig() { local WEBSERVER="${3:-http://localhost:8080}" local NOCHECK=false diff --git a/test/integration/test-apt-update-expected-size b/test/integration/test-apt-update-expected-size index 7efccaa57..55a5da848 100755 --- a/test/integration/test-apt-update-expected-size +++ b/test/integration/test-apt-update-expected-size @@ -26,6 +26,7 @@ test_inreleasetoobig() { } test_packagestoobig() { + redatereleasefiles '+1hour' # append junk at the end of the Packages.gz/Packages SIZE="$(stat --printf=%s aptarchive/dists/unstable/main/binary-i386/Packages)" find aptarchive/dists -name 'Packages*' | while read pkg; do diff --git a/test/integration/test-apt-update-not-modified b/test/integration/test-apt-update-not-modified index 2dc56e76c..a67ecb760 100755 --- a/test/integration/test-apt-update-not-modified +++ b/test/integration/test-apt-update-not-modified @@ -12,7 +12,7 @@ insertpackage 'unstable' 'apt' 'all' '1.0' setupaptarchive --no-update methodtest() { - msgmsg 'Test with' "$1" + msgmsg 'Test InRelease with' "$1" rm -rf rootdir/var/lib/apt/lists # get our cache populated testsuccess aptget update @@ -36,6 +36,62 @@ Reading package lists..." aptget update Get:1 $1 unstable/main amd64 Packages [$(stat -c '%s' 'aptarchive/dists/unstable/main/binary-amd64/Packages.gz') B] Reading package lists..." aptget update testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" + + webserverconfig 'aptwebserver::support::modified-since' 'false' + webserverconfig 'aptwebserver::support::last-modified' 'false' + testsuccessequal "Get:1 $1 unstable InRelease [$(stat -c '%s' 'aptarchive/dists/unstable/InRelease') B] +Reading package lists..." aptget update + webserverconfig 'aptwebserver::support::modified-since' 'true' + webserverconfig 'aptwebserver::support::last-modified' 'true' + + msgmsg 'Test Release.gpg with' "$1" + rm -rf rootdir/var/lib/apt/lists + cp -a aptarchive/dists aptarchive/dists.good + find aptarchive/dists -name 'InRelease' -delete + # get our cache populated + testsuccess aptget update + listcurrentlistsdirectory > listsdir.lst + + # hit again with a good cache + testsuccessequal "Ign $1 unstable InRelease + 404 Not Found +Hit $1 unstable Release +Hit $1 unstable Release.gpg +Reading package lists..." aptget update + testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" + + # drop an architecture, which means the file should be gone now + configarchitecture 'i386' + sed '/_binary-amd64_Packages/ d' listsdir.lst > listsdir-without-amd64.lst + testsuccessequal "Ign $1 unstable InRelease + 404 Not Found +Hit $1 unstable Release +Hit $1 unstable Release.gpg +Reading package lists..." aptget update + testfileequal 'listsdir-without-amd64.lst' "$(listcurrentlistsdirectory)" + + # readd arch so its downloaded again + configarchitecture 'amd64' 'i386' + testsuccessequal "Ign $1 unstable InRelease + 404 Not Found +Hit $1 unstable Release +Hit $1 unstable Release.gpg +Get:1 $1 unstable/main amd64 Packages [$(stat -c '%s' 'aptarchive/dists/unstable/main/binary-amd64/Packages.gz') B] +Reading package lists..." aptget update + testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" + + webserverconfig 'aptwebserver::support::modified-since' 'false' + webserverconfig 'aptwebserver::support::last-modified' 'false' + testsuccessequal "Ign $1 unstable InRelease + 404 Not Found +Get:1 $1 unstable Release [$(stat -c '%s' 'aptarchive/dists/unstable/Release') B] +Get:2 $1 unstable Release.gpg [$(stat -c '%s' 'aptarchive/dists/unstable/Release.gpg') B] +Reading package lists..." aptget update + webserverconfig 'aptwebserver::support::modified-since' 'true' + webserverconfig 'aptwebserver::support::last-modified' 'true' + + rm -rf aptarchive/dists + cp -a aptarchive/dists.good aptarchive/dists } changetowebserver diff --git a/test/integration/test-apt-update-rollback b/test/integration/test-apt-update-rollback index f4500b69d..29fe1ab56 100755 --- a/test/integration/test-apt-update-rollback +++ b/test/integration/test-apt-update-rollback @@ -158,6 +158,7 @@ test_inrelease_to_broken_gzip() { msgmsg "Test InRelease to broken gzip" start_with_good_inrelease + redatereleasefiles '+2hours' # append junk at the end of the compressed file echo "lala" >> $APTARCHIVE/dists/unstable/main/source/Sources.gz touch -d '+2min' $APTARCHIVE/dists/unstable/main/source/Sources.gz diff --git a/test/integration/test-apt-update-transactions b/test/integration/test-apt-update-transactions index 67dd633f9..63b318056 100755 --- a/test/integration/test-apt-update-transactions +++ b/test/integration/test-apt-update-transactions @@ -47,6 +47,7 @@ testrun() { testsetup() { msgmsg 'Test with no initial data over' "$1" + redatereleasefiles 'now' rm -rf rootdir/var/lib/apt/lists mkdir -p rootdir/var/lib/apt/lists/partial listcurrentlistsdirectory > listsdir.lst @@ -55,6 +56,7 @@ testsetup() { msgmsg 'Test with initial data over' "$1" testsuccess aptget update listcurrentlistsdirectory > listsdir.lst + redatereleasefiles '+1hour' testrun 'listsdir.lst' } -- cgit v1.2.3-70-g09d2 From 6bf93605fdb8e858d3f0a79a124c1d39f760094d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 18 May 2015 22:15:06 +0200 Subject: treat older Release files than we already have as an IMSHit Valid-Until protects us from long-living downgrade attacks, but not all repositories have it and an attacker could still use older but still valid files to downgrade us. While this makes it sounds like a security improvement now, its a bit theoretical at best as an attacker with capabilities to pull this off could just as well always keep us days (but in the valid period) behind and always knows which state we have, as we tell him with the If-Modified-Since header. This is also why this is 'silently' ignored and treated as an IMSHit rather than screamed at the user as this can at best be an annoyance for attackers. An error here would 'regularily' be encountered by users by out-of-sync mirrors serving a single run (e.g. load balancer) or in two consecutive runs on the other hand, so it would just help teaching people ignore it. That said, most of the code churn is caused by enforcing this additional requirement. Crisscross from InRelease to Release.gpg is e.g. very unlikely in practice, but if we would ignore it an attacker could sidestep it this way. --- apt-pkg/acquire-item.cc | 264 ++++++++++++++++++------- apt-pkg/acquire-item.h | 105 +++++----- apt-pkg/indexrecords.cc | 28 +-- apt-pkg/indexrecords.h | 2 + test/integration/framework | 7 +- test/integration/test-apt-update-ims | 12 +- test/integration/test-apt-update-nofallback | 5 +- test/integration/test-apt-update-not-modified | 4 - test/integration/test-apt-update-rollback | 4 +- test/integration/test-releasefile-date-older | 62 ++++++ test/integration/test-releasefile-valid-until | 37 ++-- test/integration/test-releasefile-verification | 70 +++---- 12 files changed, 383 insertions(+), 217 deletions(-) create mode 100755 test/integration/test-releasefile-date-older (limited to 'test/integration/framework') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 78dace12c..8155b9bfe 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -1637,7 +1637,7 @@ pkgAcqMetaBase::pkgAcqMetaBase(pkgAcquire *Owner, HashStringList const &ExpectedHashes, pkgAcqMetaBase *TransactionManager) : Item(Owner, ExpectedHashes, TransactionManager), - MetaIndexParser(MetaIndexParser), IndexTargets(IndexTargets), + MetaIndexParser(MetaIndexParser), LastMetaIndexParser(NULL), IndexTargets(IndexTargets), AuthPass(false), RealURI(RealURI), IMSHit(false) { } @@ -1697,6 +1697,14 @@ void pkgAcqMetaBase::CommitTransaction() Transaction.clear(); } /*}}}*/ +bool pkgAcqMetaBase::TransactionState(TransactionStates const state) /*{{{*/ +{ + // Do not remove InRelease on IMSHit of Release.gpg [yes, this is very edgecasey] + if (TransactionManager->IMSHit == false) + return pkgAcquire::Item::TransactionState(state); + return true; +} + /*}}}*/ // AcqMetaBase::TransactionStageCopy - Stage a file for copying /*{{{*/ void pkgAcqMetaBase::TransactionStageCopy(Item *I, const std::string &From, @@ -1715,15 +1723,15 @@ void pkgAcqMetaBase::TransactionStageRemoval(Item *I, } /*}}}*/ // AcqMetaBase::GenerateAuthWarning - Check gpg authentication error /*{{{*/ -bool pkgAcqMetaBase::CheckStopAuthentication(const std::string &Message) +bool pkgAcqMetaBase::CheckStopAuthentication(pkgAcquire::Item * const I, const std::string &Message) { // FIXME: this entire function can do now that we disallow going to // a unauthenticated state and can cleanly rollback - string const Final = GetFinalFilename(); + string const Final = I->GetFinalFilename(); if(FileExists(Final)) { - Status = StatTransientNetworkError; + I->Status = StatTransientNetworkError; _error->Warning(_("An error occurred during the signature " "verification. The repository is not updated " "and the previous index files will be used. " @@ -1737,7 +1745,7 @@ bool pkgAcqMetaBase::CheckStopAuthentication(const std::string &Message) _error->Error(_("GPG error: %s: %s"), Desc.Description.c_str(), LookupTag(Message,"Message").c_str()); - Status = StatError; + I->Status = StatError; return true; } else { _error->Warning(_("GPG error: %s: %s"), @@ -1751,17 +1759,13 @@ bool pkgAcqMetaBase::CheckStopAuthentication(const std::string &Message) /*}}}*/ // AcqMetaSig::AcqMetaSig - Constructor /*{{{*/ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, - pkgAcqMetaBase *TransactionManager, - string URI,string URIDesc,string ShortDesc, - string MetaIndexFile, - const vector* IndexTargets, - indexRecords* MetaIndexParser) : - pkgAcqMetaBase(Owner, IndexTargets, MetaIndexParser, URI, - HashStringList(), TransactionManager), - MetaIndexFile(MetaIndexFile), URIDesc(URIDesc), - ShortDesc(ShortDesc) + pkgAcqMetaBase *TransactionManager, + string const &URI, string const &URIDesc,string const &ShortDesc, + pkgAcqMetaIndex * const MetaIndex) : + pkgAcquire::Item(Owner, HashStringList(), TransactionManager), MetaIndex(MetaIndex), + URIDesc(URIDesc), RealURI(URI) { - DestFile = GetPartialFileNameFromURI(RealURI); + DestFile = GetPartialFileNameFromURI(URI); // remove any partial downloaded sig-file in partial/. // it may confuse proxies and is too small to warrant a @@ -1779,11 +1783,28 @@ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, Desc.ShortDesc = ShortDesc; Desc.URI = URI; - QueueURI(Desc); + // If we got a hit for Release, we will get one for Release.gpg too (or obscure errors), + // so we skip the download step and go instantly to verification + if (TransactionManager->IMSHit == true && RealFileExists(GetFinalFilename())) + { + Complete = true; + Status = StatDone; + PartialFile = DestFile = GetFinalFilename(); + MetaIndexFileSignature = DestFile; + MetaIndex->QueueForSignatureVerify(this, MetaIndex->DestFile, DestFile); + } + else + QueueURI(Desc); } /*}}}*/ pkgAcqMetaSig::~pkgAcqMetaSig() /*{{{*/ { +} + /*}}}*/ +// pkgAcqMetaSig::GetFinalFilename - Return the full final file path /*{{{*/ +std::string pkgAcqMetaSig::GetFinalFilename() const +{ + return GetFinalFileNameFromURI(RealURI); } /*}}}*/ // pkgAcqMetaSig::Done - The signature was downloaded/verified /*{{{*/ @@ -1793,21 +1814,32 @@ void pkgAcqMetaSig::Done(string Message,unsigned long long Size, HashStringList const &Hashes, pkgAcquire::MethodConfig *Cfg) { + if (MetaIndexFileSignature.empty() == false) + { + DestFile = MetaIndexFileSignature; + MetaIndexFileSignature.clear(); + } Item::Done(Message, Size, Hashes, Cfg); - if(AuthPass == false) + if(MetaIndex->AuthPass == false) { - if(CheckDownloadDone(Message, Hashes) == true) + if(MetaIndex->CheckDownloadDone(this, Message, Hashes) == true) { - // destfile will be modified to point to MetaIndexFile for the - // gpgv method, so we need to save it here - MetaIndexFileSignature = DestFile; - QueueForSignatureVerify(MetaIndexFile, MetaIndexFileSignature); + // destfile will be modified to point to MetaIndexFile for the + // gpgv method, so we need to save it here + MetaIndexFileSignature = DestFile; + MetaIndex->QueueForSignatureVerify(this, MetaIndex->DestFile, DestFile); } return; } - else if(CheckAuthDone(Message) == true) - TransactionManager->TransactionStageCopy(this, MetaIndexFileSignature, GetFinalFilename()); + else if(MetaIndex->CheckAuthDone(Message) == true) + { + if (TransactionManager->IMSHit == false) + { + TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename()); + TransactionManager->TransactionStageCopy(MetaIndex, MetaIndex->DestFile, MetaIndex->GetFinalFilename()); + } + } } /*}}}*/ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/ @@ -1815,20 +1847,18 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/ Item::Failed(Message,Cnf); // check if we need to fail at this point - if (AuthPass == true && CheckStopAuthentication(Message)) + if (MetaIndex->AuthPass == true && MetaIndex->CheckStopAuthentication(this, Message)) return; - // FIXME: meh, this is not really elegant - string const Final = GetFinalFileNameFromURI(RealURI); - string const InReleaseURI = RealURI.replace(RealURI.rfind("Release.gpg"), 12, - "InRelease"); - string const FinalInRelease = GetFinalFileNameFromURI(InReleaseURI); + string const FinalRelease = MetaIndex->GetFinalFilename(); + string const FinalReleasegpg = GetFinalFilename(); + string const FinalInRelease = TransactionManager->GetFinalFilename(); - if (RealFileExists(Final) || RealFileExists(FinalInRelease)) + if (RealFileExists(FinalReleasegpg) || RealFileExists(FinalInRelease)) { std::string downgrade_msg; strprintf(downgrade_msg, _("The repository '%s' is no longer signed."), - URIDesc.c_str()); + MetaIndex->URIDesc.c_str()); if(_config->FindB("Acquire::AllowDowngradeToInsecureRepositories")) { // meh, the users wants to take risks (we still mark the packages @@ -1841,7 +1871,7 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/ } else { _error->Error("%s", downgrade_msg.c_str()); if (TransactionManager->IMSHit == false) - Rename(MetaIndexFile, MetaIndexFile+".FAILED"); + Rename(MetaIndex->DestFile, MetaIndex->DestFile + ".FAILED"); Item::Failed("Message: " + downgrade_msg, Cnf); TransactionManager->AbortTransaction(); return; @@ -1850,23 +1880,44 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/ else _error->Warning(_("The data from '%s' is not signed. Packages " "from that repository can not be authenticated."), - URIDesc.c_str()); + MetaIndex->URIDesc.c_str()); - // this ensures that any file in the lists/ dir is removed by the - // transaction - DestFile = GetPartialFileNameFromURI(RealURI); + // ensures that a Release.gpg file in the lists/ is removed by the transaction TransactionManager->TransactionStageRemoval(this, DestFile); // only allow going further if the users explicitely wants it - if(AllowInsecureRepositories(MetaIndexParser, TransactionManager, this) == true) + if(AllowInsecureRepositories(MetaIndex->MetaIndexParser, TransactionManager, this) == true) { + if (RealFileExists(FinalReleasegpg) || RealFileExists(FinalInRelease)) + { + // open the last Release if we have it + if (TransactionManager->IMSHit == false) + { + MetaIndex->LastMetaIndexParser = new indexRecords; + _error->PushToStack(); + if (RealFileExists(FinalInRelease)) + MetaIndex->LastMetaIndexParser->Load(FinalInRelease); + else + MetaIndex->LastMetaIndexParser->Load(FinalRelease); + // its unlikely to happen, but if what we have is bad ignore it + if (_error->PendingError()) + { + delete MetaIndex->LastMetaIndexParser; + MetaIndex->LastMetaIndexParser = NULL; + } + _error->RevertToStack(); + } + } + // we parse the indexes here because at this point the user wanted // a repository that may potentially harm him - MetaIndexParser->Load(MetaIndexFile); - if (!VerifyVendor(Message)) + MetaIndex->MetaIndexParser->Load(MetaIndex->DestFile); + if (MetaIndex->VerifyVendor(Message) == false) /* expired Release files are still a problem you need extra force for */; else - QueueIndexes(true); + MetaIndex->QueueIndexes(true); + + TransactionManager->TransactionStageCopy(MetaIndex, MetaIndex->DestFile, MetaIndex->GetFinalFilename()); } // FIXME: this is used often (e.g. in pkgAcqIndexTrans) so refactor @@ -1926,18 +1977,14 @@ void pkgAcqMetaIndex::Done(string Message,unsigned long long Size, /*{{{*/ { Item::Done(Message,Size,Hashes,Cfg); - if(CheckDownloadDone(Message, Hashes)) + if(CheckDownloadDone(this, Message, Hashes)) { // we have a Release file, now download the Signature, all further // verify/queue for additional downloads will be done in the // pkgAcqMetaSig::Done() code - std::string const MetaIndexFile = DestFile; - new pkgAcqMetaSig(Owner, TransactionManager, + new pkgAcqMetaSig(Owner, TransactionManager, MetaIndexSigURI, MetaIndexSigURIDesc, - MetaIndexSigShortDesc, MetaIndexFile, IndexTargets, - MetaIndexParser); - - TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename()); + MetaIndexSigShortDesc, this); } } /*}}}*/ @@ -1948,6 +1995,40 @@ bool pkgAcqMetaBase::CheckAuthDone(string Message) /*{{{*/ // perform additional verification of its contents, and use them // to verify the indexes we are about to download + if (TransactionManager->IMSHit == false) + { + // open the last (In)Release if we have it + std::string const FinalFile = GetFinalFilename(); + std::string FinalRelease; + std::string FinalInRelease; + if (APT::String::Endswith(FinalFile, "InRelease")) + { + FinalInRelease = FinalFile; + FinalRelease = FinalFile.substr(0, FinalFile.length() - strlen("InRelease")) + "Release"; + } + else + { + FinalInRelease = FinalFile.substr(0, FinalFile.length() - strlen("Release")) + "InRelease"; + FinalRelease = FinalFile; + } + if (RealFileExists(FinalInRelease) || RealFileExists(FinalRelease)) + { + LastMetaIndexParser = new indexRecords; + _error->PushToStack(); + if (RealFileExists(FinalInRelease)) + LastMetaIndexParser->Load(FinalInRelease); + else + LastMetaIndexParser->Load(FinalRelease); + // its unlikely to happen, but if what we have is bad ignore it + if (_error->PendingError()) + { + delete LastMetaIndexParser; + LastMetaIndexParser = NULL; + } + _error->RevertToStack(); + } + } + if (!MetaIndexParser->Load(DestFile)) { Status = StatAuthError; @@ -2001,48 +2082,47 @@ std::string pkgAcqMetaBase::GetFinalFilename() const } /*}}}*/ // pkgAcqMetaBase::QueueForSignatureVerify /*{{{*/ -void pkgAcqMetaBase::QueueForSignatureVerify(const std::string &MetaIndexFile, - const std::string &MetaIndexFileSignature) +void pkgAcqMetaBase::QueueForSignatureVerify(pkgAcquire::Item * const I, std::string const &File, std::string const &Signature) { AuthPass = true; - Desc.URI = "gpgv:" + MetaIndexFileSignature; - DestFile = MetaIndexFile; - QueueURI(Desc); - SetActiveSubprocess("gpgv"); + I->Desc.URI = "gpgv:" + Signature; + I->DestFile = File; + QueueURI(I->Desc); + I->SetActiveSubprocess("gpgv"); } /*}}}*/ // pkgAcqMetaBase::CheckDownloadDone /*{{{*/ -bool pkgAcqMetaBase::CheckDownloadDone(const std::string &Message, HashStringList const &Hashes) +bool pkgAcqMetaBase::CheckDownloadDone(pkgAcquire::Item * const I, const std::string &Message, HashStringList const &Hashes) const { // We have just finished downloading a Release file (it is not // verified yet) - string FileName = LookupTag(Message,"Filename"); + string const FileName = LookupTag(Message,"Filename"); if (FileName.empty() == true) { - Status = StatError; - ErrorText = "Method gave a blank filename"; + I->Status = StatError; + I->ErrorText = "Method gave a blank filename"; return false; } - if (FileName != DestFile) + if (FileName != I->DestFile) { - Local = true; - Desc.URI = "copy:" + FileName; - QueueURI(Desc); + I->Local = true; + I->Desc.URI = "copy:" + FileName; + I->QueueURI(I->Desc); return false; } // make sure to verify against the right file on I-M-S hit - IMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false); - if (IMSHit == false) + bool IMSHit = StringToBool(LookupTag(Message,"IMS-Hit"), false); + if (IMSHit == false && Hashes.usable()) { // detect IMS-Hits servers haven't detected by Hash comparison - std::string FinalFile = GetFinalFilename(); + std::string const FinalFile = I->GetFinalFilename(); if (RealFileExists(FinalFile) && Hashes.VerifyFile(FinalFile) == true) { IMSHit = true; - unlink(DestFile.c_str()); + unlink(I->DestFile.c_str()); } } @@ -2052,11 +2132,11 @@ bool pkgAcqMetaBase::CheckDownloadDone(const std::string &Message, HashStringLis // even if it doesn't exist. if (TransactionManager != NULL) TransactionManager->IMSHit = true; - DestFile = GetFinalFilename(); + I->PartialFile = I->DestFile = I->GetFinalFilename(); } // set Item to complete as the remaining work is all local (verify etc) - Complete = true; + I->Complete = true; return true; } @@ -2175,6 +2255,19 @@ bool pkgAcqMetaBase::VerifyVendor(string Message) /*{{{*/ } } + /* Did we get a file older than what we have? This is a last minute IMS hit and doubles + as a prevention of downgrading us to older (still valid) files */ + if (TransactionManager->IMSHit == false && LastMetaIndexParser != NULL && + LastMetaIndexParser->GetDate() > MetaIndexParser->GetDate()) + { + TransactionManager->IMSHit = true; + unlink(DestFile.c_str()); + PartialFile = DestFile = GetFinalFilename(); + delete MetaIndexParser; + MetaIndexParser = LastMetaIndexParser; + LastMetaIndexParser = NULL; + } + if (_config->FindB("Debug::pkgAcquire::Auth", false)) { std::cerr << "Got Codename: " << MetaIndexParser->GetDist() << std::endl; @@ -2248,7 +2341,6 @@ pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire *Owner, /*{{{*/ { // index targets + (worst case:) Release/Release.gpg ExpectedAdditionalItems = IndexTargets->size() + 2; - } /*}}}*/ pkgAcqMetaClearSig::~pkgAcqMetaClearSig() /*{{{*/ @@ -2268,14 +2360,25 @@ string pkgAcqMetaClearSig::Custom600Headers() } /*}}}*/ // pkgAcqMetaClearSig::Done - We got a file /*{{{*/ -// --------------------------------------------------------------------- +class APT_HIDDEN DummyItem : public pkgAcquire::Item +{ + std::string URI; + public: + virtual std::string DescURI() {return URI;}; + + DummyItem(pkgAcquire *Owner, std::string const &URI) : pkgAcquire::Item(Owner), URI(URI) + { + Status = StatDone; + DestFile = GetFinalFileNameFromURI(URI); + } +}; void pkgAcqMetaClearSig::Done(std::string Message,unsigned long long Size, HashStringList const &Hashes, pkgAcquire::MethodConfig *Cnf) { Item::Done(Message, Size, Hashes, Cnf); - // if we expect a ClearTextSignature (InRelase), ensure that + // if we expect a ClearTextSignature (InRelease), ensure that // this is what we get and if not fail to queue a // Release/Release.gpg, see #346386 if (FileExists(DestFile) && !StartsWithGPGClearTextSignature(DestFile)) @@ -2288,12 +2391,23 @@ void pkgAcqMetaClearSig::Done(std::string Message,unsigned long long Size, if(AuthPass == false) { - if(CheckDownloadDone(Message, Hashes) == true) - QueueForSignatureVerify(DestFile, DestFile); + if(CheckDownloadDone(this, Message, Hashes) == true) + QueueForSignatureVerify(this, DestFile, DestFile); return; } else if(CheckAuthDone(Message) == true) - TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename()); + { + if (TransactionManager->IMSHit == false) + TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename()); + else if (RealFileExists(GetFinalFilename()) == false) + { + // We got an InRelease file IMSHit, but we haven't one, which means + // we had a valid Release/Release.gpg combo stepping in, which we have + // to 'acquire' now to ensure list cleanup isn't removing them + new DummyItem(Owner, MetaIndexURI); + new DummyItem(Owner, MetaSigURI); + } + } } /*}}}*/ void pkgAcqMetaClearSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/ @@ -2318,7 +2432,7 @@ void pkgAcqMetaClearSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /* } else { - if(CheckStopAuthentication(Message)) + if(CheckStopAuthentication(this, Message)) return; _error->Warning(_("The data from '%s' is not signed. Packages " diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index 646de8416..07c86f31b 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -394,6 +394,7 @@ class pkgAcqMetaBase : public pkgAcquire::Item /*{{{*/ /** \brief A package-system-specific parser for the meta-index file. */ indexRecords *MetaIndexParser; + indexRecords *LastMetaIndexParser; /** \brief The index files which should be looked up in the meta-index * and then downloaded. @@ -429,11 +430,10 @@ class pkgAcqMetaBase : public pkgAcquire::Item /*{{{*/ * \param Message The message block received from the fetch * subprocess. */ - bool CheckDownloadDone(const std::string &Message, HashStringList const &Hashes); + bool CheckDownloadDone(pkgAcquire::Item * const I, const std::string &Message, HashStringList const &Hashes) const; /** \brief Queue the downloaded Signature for verification */ - void QueueForSignatureVerify(const std::string &MetaIndexFile, - const std::string &MetaIndexFileSignature); + void QueueForSignatureVerify(pkgAcquire::Item * const I, std::string const &File, std::string const &Signature); #if APT_PKG_ABI >= 413 virtual std::string Custom600Headers() const; @@ -453,7 +453,7 @@ class pkgAcqMetaBase : public pkgAcquire::Item /*{{{*/ bool CheckAuthDone(std::string Message); /** Check if the current item should fail at this point */ - bool CheckStopAuthentication(const std::string &Message); + bool CheckStopAuthentication(pkgAcquire::Item * const I, const std::string &Message); /** \brief Check that the release file is a release file for the * correct distribution. @@ -462,8 +462,7 @@ class pkgAcqMetaBase : public pkgAcquire::Item /*{{{*/ */ bool VerifyVendor(std::string Message); - /** \brief Get the full pathname of the final file for the current URI */ - virtual std::string GetFinalFilename() const; + virtual bool TransactionState(TransactionStates const state); public: // This refers more to the Transaction-Manager than the actual file @@ -487,6 +486,9 @@ class pkgAcqMetaBase : public pkgAcquire::Item /*{{{*/ */ void TransactionStageRemoval(Item *I, const std::string &FinalFile); + /** \brief Get the full pathname of the final file for the current URI */ + virtual std::string GetFinalFilename() const; + pkgAcqMetaBase(pkgAcquire *Owner, const std::vector* IndexTargets, indexRecords* MetaIndexParser, @@ -495,50 +497,6 @@ class pkgAcqMetaBase : public pkgAcquire::Item /*{{{*/ pkgAcqMetaBase *TransactionManager=NULL); }; /*}}}*/ -/** \brief An acquire item that downloads the detached signature {{{ - * of a meta-index (Release) file, then queues up the release - * file itself. - * - * \todo Why protected members? - * - * \sa pkgAcqMetaIndex - */ -class APT_HIDDEN pkgAcqMetaSig : public pkgAcqMetaBase -{ - void *d; - - protected: - - /** \brief The file we need to verify */ - std::string MetaIndexFile; - - /** \brief The file we use to verify the MetaIndexFile with */ - std::string MetaIndexFileSignature; - - /** \brief Long URI description used in the acquire system */ - std::string URIDesc; - - /** \brief Short URI description used in the acquire system */ - std::string ShortDesc; - - public: - - // Specialized action members - virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf); - virtual void Done(std::string Message,unsigned long long Size, - HashStringList const &Hashes, - pkgAcquire::MethodConfig *Cnf); - - /** \brief Create a new pkgAcqMetaSig. */ - pkgAcqMetaSig(pkgAcquire *Owner, - pkgAcqMetaBase *TransactionManager, - std::string URI,std::string URIDesc, std::string ShortDesc, - std::string MetaIndexFile, - const std::vector* IndexTargets, - indexRecords* MetaIndexParser); - virtual ~pkgAcqMetaSig(); -}; - /*}}}*/ /** \brief An item that is responsible for downloading the meta-index {{{ * file (i.e., Release) itself and verifying its signature. * @@ -584,6 +542,53 @@ class APT_HIDDEN pkgAcqMetaIndex : public pkgAcqMetaBase std::string MetaIndexSigURI, std::string MetaIndexSigURIDesc, std::string MetaIndexSigShortDesc, const std::vector* IndexTargets, indexRecords* MetaIndexParser); + + friend class pkgAcqMetaSig; +}; + /*}}}*/ +/** \brief An acquire item that downloads the detached signature {{{ + * of a meta-index (Release) file, then queues up the release + * file itself. + * + * \todo Why protected members? + * + * \sa pkgAcqMetaIndex + */ +class APT_HIDDEN pkgAcqMetaSig : public pkgAcquire::Item +{ + void *d; + + pkgAcqMetaIndex * const MetaIndex; + + /** \brief The file we use to verify the MetaIndexFile with (not always set!) */ + std::string MetaIndexFileSignature; + + protected: + + /** \brief Long URI description used in the acquire system */ + std::string URIDesc; + + /** \brief URI used to get the file */ + std::string RealURI; + + /** \brief Get the full pathname of the final file for the current URI */ + virtual std::string GetFinalFilename() const; + + public: + virtual std::string DescURI() {return RealURI;}; + + // Specialized action members + virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf); + virtual void Done(std::string Message,unsigned long long Size, + HashStringList const &Hashes, + pkgAcquire::MethodConfig *Cnf); + + /** \brief Create a new pkgAcqMetaSig. */ + pkgAcqMetaSig(pkgAcquire *Owner, + pkgAcqMetaBase *TransactionManager, + std::string const &URI,std::string const &URIDesc, + std::string const &ShortDesc, pkgAcqMetaIndex * const MetaIndex); + virtual ~pkgAcqMetaSig(); }; /*}}}*/ /** \brief An item repsonsible for downloading clearsigned metaindexes {{{*/ diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc index d65266f64..de2617833 100644 --- a/apt-pkg/indexrecords.cc +++ b/apt-pkg/indexrecords.cc @@ -58,6 +58,11 @@ APT_PURE time_t indexRecords::GetValidUntil() const return this->ValidUntil; } +APT_PURE time_t indexRecords::GetDate() const +{ + return this->Date; +} + APT_PURE indexRecords::checkSum *indexRecords::Lookup(const string MetaKey) { std::map::const_iterator sum = Entries.find(MetaKey); @@ -133,9 +138,15 @@ bool indexRecords::Load(const string Filename) /*{{{*/ return false; } - string Label = Section.FindS("Label"); - string StrDate = Section.FindS("Date"); - string StrValidUntil = Section.FindS("Valid-Until"); + string const StrDate = Section.FindS("Date"); + if (RFC1123StrToTime(StrDate.c_str(), Date) == false) + { + strprintf(ErrorText, _("Invalid 'Date' entry in Release file %s"), Filename.c_str()); + return false; + } + + string const Label = Section.FindS("Label"); + string const StrValidUntil = Section.FindS("Valid-Until"); // if we have a Valid-Until header in the Release file, use it as default if (StrValidUntil.empty() == false) @@ -158,20 +169,13 @@ bool indexRecords::Load(const string Filename) /*{{{*/ (MinAge == 0 || ValidUntil == 0)) // No user settings, use the one from the Release file return true; - time_t date; - if (RFC1123StrToTime(StrDate.c_str(), date) == false) - { - strprintf(ErrorText, _("Invalid 'Date' entry in Release file %s"), Filename.c_str()); - return false; - } - if (MinAge != 0 && ValidUntil != 0) { - time_t const min_date = date + MinAge; + time_t const min_date = Date + MinAge; if (ValidUntil < min_date) ValidUntil = min_date; } if (MaxAge != 0) { - time_t const max_date = date + MaxAge; + time_t const max_date = Date + MaxAge; if (ValidUntil == 0 || ValidUntil > max_date) ValidUntil = max_date; } diff --git a/apt-pkg/indexrecords.h b/apt-pkg/indexrecords.h index 35e534c12..6ed5f0c2b 100644 --- a/apt-pkg/indexrecords.h +++ b/apt-pkg/indexrecords.h @@ -36,6 +36,7 @@ class indexRecords std::string Dist; std::string Suite; std::string ExpectedDist; + time_t Date; time_t ValidUntil; bool SupportsAcquireByHash; @@ -62,6 +63,7 @@ class indexRecords std::string GetSuite() const; bool GetSupportsAcquireByHash() const; time_t GetValidUntil() const; + time_t GetDate() const; std::string GetExpectedDist() const; /** \brief check if source is marked as always trusted */ diff --git a/test/integration/framework b/test/integration/framework index 8c8936ead..b253deb91 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1164,9 +1164,9 @@ testfileequal() { shift msgtest "Test for correctness of file" "$FILE" if [ -z "$*" ]; then - echo -n "" | checkdiff $FILE - && msgpass || msgfail + echo -n "" | checkdiff - $FILE && msgpass || msgfail else - echo "$*" | checkdiff $FILE - && msgpass || msgfail + echo "$*" | checkdiff - $FILE && msgpass || msgfail fi } @@ -1547,7 +1547,8 @@ aptautotest_aptcdrom_add() { aptautotest_aptget_update "$@"; } testaptautotestnodpkgwarning() { local TESTCALL="$1" while [ -n "$2" ]; do - if expr match "$2" '^-[a-z]*s' >/dev/null 2>&1; then return; fi + if expr match "$2" '^-[a-z]*s' >/dev/null 2>&1; then return; fi # simulation mode + if expr match "$2" '^-dy\?' >/dev/null 2>&1; then return; fi # download-only mode shift done testfailure grep '^dpkg: warning:.*ignor.*' "${TMPWORKINGDIRECTORY}/rootdir/tmp-before/${TESTCALL}.output" diff --git a/test/integration/test-apt-update-ims b/test/integration/test-apt-update-ims index f091bffaa..7385e701a 100755 --- a/test/integration/test-apt-update-ims +++ b/test/integration/test-apt-update-ims @@ -43,7 +43,7 @@ runtest() { testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" # ensure that we still do a hash check for other files on ims hit of Release - if grep -q '^Hit .* \(InRelease\|Release.gpg\)$' expected.output ; then + if grep -q '^Hit .* InRelease$' expected.output || ! grep -q '^Ign .* Release\(\.gpg\)\?$' expected.output; then $TEST aptget update -o Debug::Acquire::gpgv=1 cp rootdir/tmp/${TEST}.output goodsign.output testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" @@ -66,7 +66,6 @@ msgmsg 'Release/Release.gpg' EXPECT='Ign http://localhost:8080 unstable InRelease 404 Not Found Hit http://localhost:8080 unstable Release -Hit http://localhost:8080 unstable Release.gpg Reading package lists...' find aptarchive -name 'InRelease' -delete echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex @@ -81,7 +80,7 @@ Hit http://localhost:8080 unstable Release Ign http://localhost:8080 unstable Release.gpg 404 Not Found Reading package lists... -W: The data from 'http://localhost:8080 unstable Release.gpg' is not signed. Packages from that repository can not be authenticated." +W: The data from 'http://localhost:8080 unstable Release' is not signed. Packages from that repository can not be authenticated." find aptarchive -name 'Release.gpg' -delete echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex runtest 'warning' @@ -108,8 +107,7 @@ msgmsg 'expired Release/Release.gpg' EXPECT='Ign http://localhost:8080 unstable InRelease 404 Not Found Hit http://localhost:8080 unstable Release -Hit http://localhost:8080 unstable Release.gpg -E: Release file for http://localhost:8080/dists/unstable/Release.gpg is expired (invalid since). Updates for this repository will not be applied.' +E: Release file for http://localhost:8080/dists/unstable/Release is expired (invalid since). Updates for this repository will not be applied.' find aptarchive -name 'InRelease' -delete echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex runtest 'failure' @@ -122,8 +120,8 @@ EXPECT="Ign http://localhost:8080 unstable InRelease Hit http://localhost:8080 unstable Release Ign http://localhost:8080 unstable Release.gpg 404 Not Found -W: The data from 'http://localhost:8080 unstable Release.gpg' is not signed. Packages from that repository can not be authenticated. -E: Release file for http://localhost:8080/dists/unstable/InRelease is expired (invalid since). Updates for this repository will not be applied." +W: The data from 'http://localhost:8080 unstable Release' is not signed. Packages from that repository can not be authenticated. +E: Release file for http://localhost:8080/dists/unstable/Release is expired (invalid since). Updates for this repository will not be applied." find aptarchive -name 'Release.gpg' -delete echo 'Acquire::GzipIndexes "0";' > rootdir/etc/apt/apt.conf.d/02compressindex runtest 'failure' 'warning' diff --git a/test/integration/test-apt-update-nofallback b/test/integration/test-apt-update-nofallback index 71576de81..db4430ea3 100755 --- a/test/integration/test-apt-update-nofallback +++ b/test/integration/test-apt-update-nofallback @@ -8,6 +8,7 @@ set -e simulate_mitm_and_inject_evil_package() { + redatereleasefiles '+1 hour' rm -f $APTARCHIVE/dists/unstable/InRelease rm -f $APTARCHIVE/dists/unstable/Release.gpg inject_evil_package @@ -31,7 +32,7 @@ EOF assert_update_is_refused_and_last_good_state_used() { - testfailureequal "E: The repository 'file: unstable Release.gpg' is no longer signed." aptget update -qq + testfailuremsg "E: The repository 'file: unstable Release' is no longer signed." aptget update assert_repo_is_intact } @@ -193,7 +194,7 @@ test_release_gpg_to_invalid_release_release_gpg() echo "Some evil data" >> $APTARCHIVE/dists/unstable/Release inject_evil_package - testwarningequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable Release.gpg: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) + testwarningequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable Release: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) W: Failed to fetch file:${APTARCHIVE}/dists/unstable/Release.gpg The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) diff --git a/test/integration/test-apt-update-not-modified b/test/integration/test-apt-update-not-modified index a67ecb760..b1d55c156 100755 --- a/test/integration/test-apt-update-not-modified +++ b/test/integration/test-apt-update-not-modified @@ -56,7 +56,6 @@ Reading package lists..." aptget update testsuccessequal "Ign $1 unstable InRelease 404 Not Found Hit $1 unstable Release -Hit $1 unstable Release.gpg Reading package lists..." aptget update testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" @@ -66,7 +65,6 @@ Reading package lists..." aptget update testsuccessequal "Ign $1 unstable InRelease 404 Not Found Hit $1 unstable Release -Hit $1 unstable Release.gpg Reading package lists..." aptget update testfileequal 'listsdir-without-amd64.lst' "$(listcurrentlistsdirectory)" @@ -75,7 +73,6 @@ Reading package lists..." aptget update testsuccessequal "Ign $1 unstable InRelease 404 Not Found Hit $1 unstable Release -Hit $1 unstable Release.gpg Get:1 $1 unstable/main amd64 Packages [$(stat -c '%s' 'aptarchive/dists/unstable/main/binary-amd64/Packages.gz') B] Reading package lists..." aptget update testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" @@ -85,7 +82,6 @@ Reading package lists..." aptget update testsuccessequal "Ign $1 unstable InRelease 404 Not Found Get:1 $1 unstable Release [$(stat -c '%s' 'aptarchive/dists/unstable/Release') B] -Get:2 $1 unstable Release.gpg [$(stat -c '%s' 'aptarchive/dists/unstable/Release.gpg') B] Reading package lists..." aptget update webserverconfig 'aptwebserver::support::modified-since' 'true' webserverconfig 'aptwebserver::support::last-modified' 'true' diff --git a/test/integration/test-apt-update-rollback b/test/integration/test-apt-update-rollback index 29fe1ab56..b464a04a1 100755 --- a/test/integration/test-apt-update-rollback +++ b/test/integration/test-apt-update-rollback @@ -78,7 +78,7 @@ test_inrelease_to_valid_release() { rm $APTARCHIVE/dists/unstable/Release.gpg # update fails - testfailureequal "E: The repository 'file: unstable Release.gpg' is no longer signed." aptget update -qq + testfailureequal "E: The repository 'file: unstable Release' is no longer signed." aptget update -qq # test that security downgrade was not successful testfileequal lists.before "$(listcurrentlistsdirectory)" @@ -101,7 +101,7 @@ test_inrelease_to_release_reverts_all() { break_repository_sources_index '+1hour' # ensure error - testfailureequal "E: The repository 'file: unstable Release.gpg' is no longer signed." aptget update -qq # -o Debug::acquire::transaction=1 + testfailureequal "E: The repository 'file: unstable Release' is no longer signed." aptget update -qq # -o Debug::acquire::transaction=1 # ensure that the Packages file is also rolled back testfileequal lists.before "$(listcurrentlistsdirectory)" diff --git a/test/integration/test-releasefile-date-older b/test/integration/test-releasefile-date-older new file mode 100755 index 000000000..5cdc34fac --- /dev/null +++ b/test/integration/test-releasefile-date-older @@ -0,0 +1,62 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework +setupenvironment +configarchitecture 'i386' + +insertpackage 'wheezy' 'apt' 'all' '0.8.15' + +setupaptarchive --no-update + +# we don't complain as the server could have just sent a 'Hit' here and this +# 'downgrade attack' is usually performed by out-of-sync mirrors. Valid-Until +# catches the 'real' downgrade attacks (expect that it finds stale mirrors). +# Scaring users with an error here serves hence no point. + +msgmsg 'InRelease file is silently rejected if' 'new Date is before old Date' +rm -rf rootdir/var/lib/apt/lists +generatereleasefiles 'now' 'now + 7 days' +signreleasefiles +testsuccess aptget update +listcurrentlistsdirectory > listsdir.lst +redatereleasefiles 'now - 2 days' +testsuccess aptget update +testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" + +msgmsg 'Release.gpg file is silently rejected if' 'new Date is before old Date' +rm -rf rootdir/var/lib/apt/lists +generatereleasefiles 'now' 'now + 7 days' +signreleasefiles +find aptarchive -name 'InRelease' -delete +testsuccess aptget update +listcurrentlistsdirectory > listsdir.lst +redatereleasefiles 'now - 2 days' +find aptarchive -name 'InRelease' -delete +testsuccess aptget update +testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" + +msgmsg 'Crisscross InRelease/Release.gpg file is silently rejected if' 'new Date is before old Date' +rm -rf rootdir/var/lib/apt/lists +generatereleasefiles 'now' 'now + 7 days' +signreleasefiles +find aptarchive -name 'Release.gpg' -delete +testsuccess aptget update +listcurrentlistsdirectory > listsdir.lst +redatereleasefiles 'now - 2 days' +find aptarchive -name 'InRelease' -delete +testsuccess aptget update +testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" + +msgmsg 'Crisscross Release.gpg/InRelease file is silently rejected if' 'new Date is before old Date' +rm -rf rootdir/var/lib/apt/lists +generatereleasefiles 'now' 'now + 7 days' +signreleasefiles +find aptarchive -name 'InRelease' -delete +testsuccess aptget update +listcurrentlistsdirectory > listsdir.lst +redatereleasefiles 'now - 2 days' +find aptarchive -name 'Release.gpg' -delete +testsuccess aptget update +testfileequal 'listsdir.lst' "$(listcurrentlistsdirectory)" diff --git a/test/integration/test-releasefile-valid-until b/test/integration/test-releasefile-valid-until index 0d9a91254..e000abf5d 100755 --- a/test/integration/test-releasefile-valid-until +++ b/test/integration/test-releasefile-valid-until @@ -16,13 +16,12 @@ setupaptarchive --no-update runtest() { local MSG="$1" - msgtest "$1" "$2" + msgtest "Release file is $MSG as it has" "$2" rm -rf rootdir/var/lib/apt/lists - aptget clean generatereleasefiles "$3" "$4" signreleasefiles shift 4 - if expr match "$MSG" '.*accepted.*' >/dev/null; then + if [ "$MSG" = 'accepted' ]; then testsuccess --nomsg aptget update "$@" testfailure grep -q 'is expired' rootdir/tmp/testsuccess.output else @@ -31,19 +30,19 @@ runtest() { fi } -runtest 'Release file is accepted as it has' 'no Until' '' '' -runtest 'Release file is accepted as it has' 'no Until and good Max-Valid' '' '' -o Acquire::Max-ValidTime=3600 -runtest 'Release file is rejected as it has' 'no Until, but bad Max-Valid' 'now - 2 days' '' -o Acquire::Max-ValidTime=3600 -runtest 'Release file is accepted as it has' 'good Until' 'now - 3 days' 'now + 1 day' -runtest 'Release file is rejected as it has' 'bad Until' 'now - 7 days' 'now - 4 days' -runtest 'Release file is rejected as it has' 'bad Until (ignore good Max-Valid)' 'now - 7 days' 'now - 4 days' -o Acquire::Max-ValidTime=1209600 -runtest 'Release file is rejected as it has' 'bad Max-Valid (bad Until)' 'now - 7 days' 'now - 4 days' -o Acquire::Max-ValidTime=86400 -runtest 'Release file is rejected as it has' 'bad Max-Valid (good Until)' 'now - 7 days' 'now + 4 days' -o Acquire::Max-ValidTime=86400 -runtest 'Release file is accepted as it has' 'good labeled Max-Valid' 'now - 7 days' 'now + 4 days' -o Acquire::Max-ValidTime=86400 -o Acquire::Max-ValidTime::Testcases=1209600 -runtest 'Release file is rejected as it has' 'bad labeled Max-Valid' 'now - 7 days' 'now + 4 days' -o Acquire::Max-ValidTime=1209600 -o Acquire::Max-ValidTime::Testcases=86400 -runtest 'Release file is accepted as it has' 'good Until (good Min-Valid, no Max-Valid)' 'now - 7 days' 'now + 1 days' -o Acquire::Min-ValidTime=1209600 -runtest 'Release file is accepted as it has' 'good Min-Valid (bad Until, no Max-Valid)' 'now - 7 days' 'now - 4 days' -o Acquire::Min-ValidTime=1209600 -runtest 'Release file is accepted as it has' 'good Min-Valid (bad Until, good Max-Valid) <' 'now - 7 days' 'now - 2 days' -o Acquire::Min-ValidTime=1209600 -o Acquire::Max-ValidTime=2419200 -runtest 'Release file is rejected as it has' 'bad Max-Valid (bad Until, good Min-Valid) >' 'now - 7 days' 'now - 2 days' -o Acquire::Max-ValidTime=12096 -o Acquire::Min-ValidTime=2419200 -runtest 'Release file is rejected as it has' 'bad Max-Valid (bad Until, bad Min-Valid) <' 'now - 7 days' 'now - 2 days' -o Acquire::Min-ValidTime=12096 -o Acquire::Max-ValidTime=241920 -runtest 'Release file is rejected as it has' 'bad Max-Valid (bad Until, bad Min-Valid) >' 'now - 7 days' 'now - 2 days' -o Acquire::Max-ValidTime=12096 -o Acquire::Min-ValidTime=241920 +runtest 'accepted' 'no Until' '' '' +runtest 'accepted' 'no Until and good Max-Valid' '' '' -o Acquire::Max-ValidTime=3600 +runtest 'rejected' 'no Until, but bad Max-Valid' 'now - 2 days' '' -o Acquire::Max-ValidTime=3600 +runtest 'accepted' 'good Until' 'now - 3 days' 'now + 1 day' +runtest 'rejected' 'bad Until' 'now - 7 days' 'now - 4 days' +runtest 'rejected' 'bad Until (ignore good Max-Valid)' 'now - 7 days' 'now - 4 days' -o Acquire::Max-ValidTime=1209600 +runtest 'rejected' 'bad Max-Valid (bad Until)' 'now - 7 days' 'now - 4 days' -o Acquire::Max-ValidTime=86400 +runtest 'rejected' 'bad Max-Valid (good Until)' 'now - 7 days' 'now + 4 days' -o Acquire::Max-ValidTime=86400 +runtest 'accepted' 'good labeled Max-Valid' 'now - 7 days' 'now + 4 days' -o Acquire::Max-ValidTime=86400 -o Acquire::Max-ValidTime::Testcases=1209600 +runtest 'rejected' 'bad labeled Max-Valid' 'now - 7 days' 'now + 4 days' -o Acquire::Max-ValidTime=1209600 -o Acquire::Max-ValidTime::Testcases=86400 +runtest 'accepted' 'good Until (good Min-Valid, no Max-Valid)' 'now - 7 days' 'now + 1 days' -o Acquire::Min-ValidTime=1209600 +runtest 'accepted' 'good Min-Valid (bad Until, no Max-Valid)' 'now - 7 days' 'now - 4 days' -o Acquire::Min-ValidTime=1209600 +runtest 'accepted' 'good Min-Valid (bad Until, good Max-Valid) <' 'now - 7 days' 'now - 2 days' -o Acquire::Min-ValidTime=1209600 -o Acquire::Max-ValidTime=2419200 +runtest 'rejected' 'bad Max-Valid (bad Until, good Min-Valid) >' 'now - 7 days' 'now - 2 days' -o Acquire::Max-ValidTime=12096 -o Acquire::Min-ValidTime=2419200 +runtest 'rejected' 'bad Max-Valid (bad Until, bad Min-Valid) <' 'now - 7 days' 'now - 2 days' -o Acquire::Min-ValidTime=12096 -o Acquire::Max-ValidTime=241920 +runtest 'rejected' 'bad Max-Valid (bad Until, bad Min-Valid) >' 'now - 7 days' 'now - 2 days' -o Acquire::Max-ValidTime=12096 -o Acquire::Min-ValidTime=241920 diff --git a/test/integration/test-releasefile-verification b/test/integration/test-releasefile-verification index 363b7fe5b..469ed34d2 100755 --- a/test/integration/test-releasefile-verification +++ b/test/integration/test-releasefile-verification @@ -91,25 +91,9 @@ touch aptarchive/apt.deb PKGFILE="${TESTDIR}/$(echo "$(basename $0)" | sed 's#^test-#Packages-#')" -updatesuccess() { - local LOG='update.log' - if aptget update >$LOG 2>&1 || grep -q -E '^(W|E): ' $LOG; then - msgpass - else - cat $LOG - msgfail - fi -} - -updatefailure() { - local LOG='update.log' - aptget update >$LOG 2>&1 || true - if grep -q -E "$1" $LOG; then - msgpass - else - cat $LOG - msgfail - fi +updatewithwarnings() { + testwarning aptget update + testsuccess grep -E "$1" rootdir/tmp/testwarning.output } runtest() { @@ -117,8 +101,8 @@ runtest() { rm -rf rootdir/var/lib/apt/lists signreleasefiles 'Joe Sixpack' find aptarchive/ -name "$DELETEFILE" -delete - msgtest 'Cold archive signed by' 'Joe Sixpack' - updatesuccess + msgmsg 'Cold archive signed by' 'Joe Sixpack' + testsuccess aptget update testsuccessequal "$(cat ${PKGFILE}) " aptcache show apt installaptold @@ -126,8 +110,8 @@ runtest() { prepare ${PKGFILE}-new signreleasefiles 'Joe Sixpack' find aptarchive/ -name "$DELETEFILE" -delete - msgtest 'Good warm archive signed by' 'Joe Sixpack' - updatesuccess + msgmsg 'Good warm archive signed by' 'Joe Sixpack' + testsuccess aptget update testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt installaptnew @@ -137,8 +121,8 @@ runtest() { cp keys/rexexpired.pub rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg signreleasefiles 'Rex Expired' find aptarchive/ -name "$DELETEFILE" -delete - msgtest 'Cold archive signed by' 'Rex Expired' - updatefailure '^W: .* KEYEXPIRED' + msgmsg 'Cold archive signed by' 'Rex Expired' + updatewithwarnings '^W: .* KEYEXPIRED' testsuccessequal "$(cat ${PKGFILE}) " aptcache show apt failaptold @@ -148,8 +132,8 @@ runtest() { rm -rf rootdir/var/lib/apt/lists signreleasefiles 'Marvin Paranoid' find aptarchive/ -name "$DELETEFILE" -delete - msgtest 'Cold archive signed by' 'Marvin Paranoid' - updatefailure '^W: .* NO_PUBKEY' + msgmsg 'Cold archive signed by' 'Marvin Paranoid' + updatewithwarnings '^W: .* NO_PUBKEY' testsuccessequal "$(cat ${PKGFILE}) " aptcache show apt failaptold @@ -162,8 +146,8 @@ runtest() { done signreleasefiles 'Joe Sixpack' find aptarchive/ -name "$DELETEFILE" -delete - msgtest 'Bad warm archive signed by' 'Joe Sixpack' - updatesuccess + msgmsg 'Bad warm archive signed by' 'Joe Sixpack' + testsuccess aptget update testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt installaptnew @@ -173,8 +157,8 @@ runtest() { rm -rf rootdir/var/lib/apt/lists signreleasefiles 'Joe Sixpack' find aptarchive/ -name "$DELETEFILE" -delete - msgtest 'Cold archive signed by' 'Joe Sixpack' - updatesuccess + msgmsg 'Cold archive signed by' 'Joe Sixpack' + testsuccess aptget update testsuccessequal "$(cat ${PKGFILE}) " aptcache show apt installaptold @@ -182,8 +166,8 @@ runtest() { prepare ${PKGFILE}-new signreleasefiles 'Marvin Paranoid' find aptarchive/ -name "$DELETEFILE" -delete - msgtest 'Good warm archive signed by' 'Marvin Paranoid' - updatefailure '^W: .* NO_PUBKEY' + msgmsg 'Good warm archive signed by' 'Marvin Paranoid' + updatewithwarnings '^W: .* NO_PUBKEY' testsuccessequal "$(cat ${PKGFILE}) " aptcache show apt installaptold @@ -192,8 +176,8 @@ runtest() { cp keys/rexexpired.pub rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg signreleasefiles 'Rex Expired' find aptarchive/ -name "$DELETEFILE" -delete - msgtest 'Good warm archive signed by' 'Rex Expired' - updatefailure '^W: .* KEYEXPIRED' + msgmsg 'Good warm archive signed by' 'Rex Expired' + updatewithwarnings '^W: .* KEYEXPIRED' testsuccessequal "$(cat ${PKGFILE}) " aptcache show apt installaptold @@ -202,8 +186,8 @@ runtest() { prepare ${PKGFILE}-new signreleasefiles find aptarchive/ -name "$DELETEFILE" -delete - msgtest 'Good warm archive signed by' 'Joe Sixpack' - updatesuccess + msgmsg 'Good warm archive signed by' 'Joe Sixpack' + testsuccess aptget update testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt installaptnew @@ -213,24 +197,24 @@ runtest2() { prepare ${PKGFILE} rm -rf rootdir/var/lib/apt/lists signreleasefiles 'Joe Sixpack' - msgtest 'Cold archive signed by' 'Joe Sixpack' - updatesuccess + msgmsg 'Cold archive signed by' 'Joe Sixpack' + testsuccess aptget update # New .deb but now an unsigned archive. For example MITM to circumvent # package verification. prepare ${PKGFILE}-new find aptarchive/ -name InRelease -delete find aptarchive/ -name Release.gpg -delete - msgtest 'Warm archive signed by' 'nobody' - updatesuccess + msgmsg 'Warm archive signed by' 'nobody' + updatewithwarnings 'W: .* no longer signed.' testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt failaptnew # Unsigned archive from the beginning must also be detected. rm -rf rootdir/var/lib/apt/lists - msgtest 'Cold archive signed by' 'nobody' - updatesuccess + msgmsg 'Cold archive signed by' 'nobody' + updatewithwarnings 'W: .* is not signed.' testsuccessequal "$(cat ${PKGFILE}-new) " aptcache show apt failaptnew -- cgit v1.2.3-70-g09d2 From 8d041b4f4f353079268039dcbfd8b5e575196b66 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 8 Jun 2015 15:22:01 +0200 Subject: do not request files if we expect an IMS hit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we have a file on disk and the hashes are the same in the new Release file and the old one we have on disk we know that if we ask the server for the file, we will at best get an IMS hit – at worse the server doesn't support this and sends us the (unchanged) file and we have to run all our checks on it again for nothing. So, we can save ourselves (and the servers) some unneeded requests if we figure this out on our own. --- apt-pkg/acquire-item.cc | 77 ++++++++++++++-------- test/integration/framework | 4 +- test/integration/test-apt-update-expected-size | 4 +- test/integration/test-apt-update-file | 25 +++++-- test/integration/test-apt-update-not-modified | 19 ++++++ test/integration/test-apt-update-rollback | 6 +- test/integration/test-apt-update-transactions | 24 +++++-- .../test-cve-2013-1051-InRelease-parsing | 13 ++-- 8 files changed, 127 insertions(+), 45 deletions(-) (limited to 'test/integration/framework') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 13e971e9f..511bbbc64 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -119,6 +119,16 @@ static bool AllowInsecureRepositories(indexRecords const * const MetaIndexParser return false; } /*}}}*/ +static HashStringList GetExpectedHashesFromFor(indexRecords * const Parser, std::string const MetaKey)/*{{{*/ +{ + if (Parser == NULL) + return HashStringList(); + indexRecords::checkSum * const R = Parser->Lookup(MetaKey); + if (R == NULL) + return HashStringList(); + return R->Hashes; +} + /*}}}*/ // all ::HashesRequired and ::GetExpectedHashes implementations /*{{{*/ /* ::GetExpectedHashes is abstract and has to be implemented by all subclasses. @@ -372,6 +382,25 @@ bool pkgAcqDiffIndex::TransactionState(TransactionStates const state) } /*}}}*/ +class APT_HIDDEN NoActionItem : public pkgAcquire::Item /*{{{*/ +/* The sole purpose of this class is having an item which does nothing to + reach its done state to prevent cleanup deleting the mentioned file. + Handy in cases in which we know we have the file already, like IMS-Hits. */ +{ + IndexTarget const * const Target; + public: + virtual std::string DescURI() const {return Target->URI;}; + virtual HashStringList GetExpectedHashes() const {return HashStringList();}; + + NoActionItem(pkgAcquire * const Owner, IndexTarget const * const Target) : + pkgAcquire::Item(Owner), Target(Target) + { + Status = StatDone; + DestFile = GetFinalFileNameFromURI(Target->URI); + } +}; + /*}}}*/ + // Acquire::Item::Item - Constructor /*{{{*/ APT_IGNORE_DEPRECATED_PUSH pkgAcquire::Item::Item(pkgAcquire * const Owner) : @@ -644,12 +673,7 @@ pkgAcqTransactionItem::~pkgAcqTransactionItem() /*{{{*/ /*}}}*/ HashStringList pkgAcqTransactionItem::GetExpectedHashesFor(std::string const MetaKey) const /*{{{*/ { - if (TransactionManager->MetaIndexParser == NULL) - return HashStringList(); - indexRecords::checkSum * const R = TransactionManager->MetaIndexParser->Lookup(MetaKey); - if (R == NULL) - return HashStringList(); - return R->Hashes; + return GetExpectedHashesFromFor(TransactionManager->MetaIndexParser, MetaKey); } /*}}}*/ @@ -939,6 +963,23 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify) /*{{{*/ return; } + if (RealFileExists(GetFinalFileNameFromURI((*Target)->URI))) + { + if (TransactionManager->LastMetaIndexParser != NULL) + { + HashStringList const newFile = GetExpectedHashesFromFor(TransactionManager->MetaIndexParser, (*Target)->MetaKey); + HashStringList const oldFile = GetExpectedHashesFromFor(TransactionManager->LastMetaIndexParser, (*Target)->MetaKey); + if (newFile == oldFile) + { + // we have the file already, no point in trying to acquire it again + new NoActionItem(Owner, *Target); + continue; + } + } + } + else + trypdiff = false; // no file to patch + // check if we have patches available trypdiff &= TransactionManager->MetaIndexParser->Exists((*Target)->MetaKey + ".diff/Index"); } @@ -1085,20 +1126,6 @@ string pkgAcqMetaClearSig::Custom600Headers() const } /*}}}*/ // pkgAcqMetaClearSig::Done - We got a file /*{{{*/ -class APT_HIDDEN DummyItem : public pkgAcquire::Item -{ - IndexTarget const * const Target; - public: - virtual std::string DescURI() const {return Target->URI;}; - virtual HashStringList GetExpectedHashes() const {return HashStringList();}; - - DummyItem(pkgAcquire * const Owner, IndexTarget const * const Target) : - pkgAcquire::Item(Owner), Target(Target) - { - Status = StatDone; - DestFile = GetFinalFileNameFromURI(Target->URI); - } -}; void pkgAcqMetaClearSig::Done(std::string const &Message, HashStringList const &Hashes, pkgAcquire::MethodConfig const * const Cnf) @@ -1131,8 +1158,8 @@ void pkgAcqMetaClearSig::Done(std::string const &Message, // We got an InRelease file IMSHit, but we haven't one, which means // we had a valid Release/Release.gpg combo stepping in, which we have // to 'acquire' now to ensure list cleanup isn't removing them - new DummyItem(Owner, &DetachedDataTarget); - new DummyItem(Owner, &DetachedSigTarget); + new NoActionItem(Owner, &DetachedDataTarget); + new NoActionItem(Owner, &DetachedSigTarget); } } } @@ -1578,11 +1605,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/ HashStringList LocalHashes; // try avoiding calculating the hash here as this is costly if (TransactionManager->LastMetaIndexParser != NULL) - { - indexRecords::checkSum * const R = TransactionManager->LastMetaIndexParser->Lookup(Target->MetaKey); - if (R != NULL) - LocalHashes = R->Hashes; - } + LocalHashes = GetExpectedHashesFromFor(TransactionManager->LastMetaIndexParser, Target->MetaKey); if (LocalHashes.usable() == false) { FileFd fd(CurrentPackagesFile, FileFd::ReadOnly); diff --git a/test/integration/framework b/test/integration/framework index b253deb91..56c4a1216 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -835,7 +835,9 @@ buildaptarchivefromincoming() { buildaptarchivefromfiles() { msginfo "Build APT archive for ${CCMD}$(basename $0)${CINFO} based on prebuild files…" - find aptarchive -name 'Packages' -o -name 'Sources' -o -name 'Translation-*' | while read line; do + local DIR='aptarchive' + if [ -d "${DIR}/dists" ]; then DIR="${DIR}/dists"; fi + find "$DIR" -name 'Packages' -o -name 'Sources' -o -name 'Translation-*' | while read line; do msgninfo "\t${line} file… " compressfile "$line" "$1" msgdone "info" diff --git a/test/integration/test-apt-update-expected-size b/test/integration/test-apt-update-expected-size index 55bba8188..24ca85133 100755 --- a/test/integration/test-apt-update-expected-size +++ b/test/integration/test-apt-update-expected-size @@ -26,7 +26,9 @@ test_inreleasetoobig() { } test_packagestoobig() { - redatereleasefiles '+1hour' + insertpackage 'unstable' 'foo' 'all' '1.0' + buildaptarchivefromfiles '+1 hour' + signreleasefiles # append junk at the end of the Packages.gz/Packages SIZE="$(stat --printf=%s aptarchive/dists/unstable/main/binary-i386/Packages)" find aptarchive/dists -name 'Packages*' | while read pkg; do diff --git a/test/integration/test-apt-update-file b/test/integration/test-apt-update-file index 665f94fa5..94b604f0e 100755 --- a/test/integration/test-apt-update-file +++ b/test/integration/test-apt-update-file @@ -26,14 +26,29 @@ testsuccess aptget update # the release files aren't an IMS-hit, but the indexes are redatereleasefiles '+1 hour' +# we don't download the index if it isn't updated testsuccess aptget update -o Debug::pkgAcquire::Auth=1 +# file:/ isn't shown in the log, so see if it was downloaded anyhow cp -a rootdir/tmp/testsuccess.output rootdir/tmp/update.output +canary="SHA512:$(bzcat aptarchive/dists/unstable/main/binary-amd64/Packages.bz2 | sha512sum |cut -f1 -d' ')" +testfailure grep -- "$canary" rootdir/tmp/update.output + +testfoo() { + # foo is still available + testsuccess aptget install -s foo + testsuccess aptcache showsrc foo + testsuccess aptget source foo --print-uris +} +testfoo + +# the release file is new again, the index still isn't, but it is somehow gone now from disk +redatereleasefiles '+2 hour' +find rootdir/var/lib/apt/lists -name '*_Packages*' -delete -# ensure that the hash of the uncompressed file was verified even on a local ims hit +testsuccess aptget update -o Debug::pkgAcquire::Auth=1 +# file:/ isn't shown in the log, so see if it was downloaded anyhow +cp -a rootdir/tmp/testsuccess.output rootdir/tmp/update.output canary="SHA512:$(bzcat aptarchive/dists/unstable/main/binary-amd64/Packages.bz2 | sha512sum |cut -f1 -d' ')" testsuccess grep -- "$canary" rootdir/tmp/update.output -# foo is still available -testsuccess aptget install -s foo -testsuccess aptcache showsrc foo -testsuccess aptget source foo --print-uris +testfoo diff --git a/test/integration/test-apt-update-not-modified b/test/integration/test-apt-update-not-modified index a490f00de..32818658f 100755 --- a/test/integration/test-apt-update-not-modified +++ b/test/integration/test-apt-update-not-modified @@ -133,6 +133,25 @@ Reading package lists..." aptget update rm -rf aptarchive/dists cp -a aptarchive/dists.good aptarchive/dists + + # new release file, but the indexes are the same + redatereleasefiles '+2 hours' + + rm -rf rootdir/var/lib/apt/lists.good + cp -a rootdir/var/lib/apt/lists rootdir/var/lib/apt/lists.good + testsuccessequal "Get:1 $1 unstable InRelease [$(stat -c '%s' 'aptarchive/dists/unstable/InRelease') B] +Reading package lists..." aptget update + + rm -rf rootdir/var/lib/apt/lists + cp -a rootdir/var/lib/apt/lists.good rootdir/var/lib/apt/lists + find rootdir/var/lib/apt/lists -name '*_Packages*' -delete + testsuccessequal "Get:1 $1 unstable InRelease [$(stat -c '%s' 'aptarchive/dists/unstable/InRelease') B] +Get:2 $1 unstable/main amd64 Packages [$(stat -c '%s' 'aptarchive/dists/unstable/main/binary-amd64/Packages.gz') B] +Get:3 $1 unstable/main i386 Packages [$(stat -c '%s' 'aptarchive/dists/unstable/main/binary-i386/Packages.gz') B] +Reading package lists..." aptget update + + rm -rf aptarchive/dists + cp -a aptarchive/dists.good aptarchive/dists } changetowebserver diff --git a/test/integration/test-apt-update-rollback b/test/integration/test-apt-update-rollback index 6fd901715..6ecf322b2 100755 --- a/test/integration/test-apt-update-rollback +++ b/test/integration/test-apt-update-rollback @@ -158,7 +158,10 @@ test_inrelease_to_broken_gzip() { msgmsg "Test InRelease to broken gzip" start_with_good_inrelease - redatereleasefiles '+2hours' + break_repository_sources_index '+1hour' + generatereleasefiles '+2hours' + signreleasefiles + # append junk at the end of the compressed file echo "lala" >> $APTARCHIVE/dists/unstable/main/source/Sources.gz touch -d '+2min' $APTARCHIVE/dists/unstable/main/source/Sources.gz @@ -166,6 +169,7 @@ test_inrelease_to_broken_gzip() { rm $APTARCHIVE/dists/unstable/main/source/Sources testfailure aptget update + testsuccess grep 'Hash Sum mismatch' rootdir/tmp/testfailure.output testfileequal lists.before "$(listcurrentlistsdirectory)" } diff --git a/test/integration/test-apt-update-transactions b/test/integration/test-apt-update-transactions index 152e1617a..a5dac1737 100755 --- a/test/integration/test-apt-update-transactions +++ b/test/integration/test-apt-update-transactions @@ -29,6 +29,12 @@ restorefile() { } testrun() { + rm -rf aptarchive/dists.good + cp -a aptarchive/dists aptarchive/dists.good + insertpackage 'unstable' 'bar' 'all' '1.0' + insertsource 'unstable' 'bar' 'all' '1.0' + buildaptarchivefromfiles '+1 hour' + # produce an unsigned repository find aptarchive \( -name 'Release.gpg' -o -name 'InRelease' \) -delete testfailure aptget update --no-allow-insecure-repositories @@ -37,20 +43,27 @@ testrun() { # signed but broken signreleasefiles + onehashbroken() { + testfailure aptget update + # each file generates two messages with this string + testequal '2' grep --count 'Hash Sum mismatch' rootdir/tmp/testfailure.output + testfileequal "$1" "$(listcurrentlistsdirectory)" + } + breakfile aptarchive/dists/unstable/main/binary-i386/Packages - testfailure aptget update - testfileequal "$1" "$(listcurrentlistsdirectory)" + onehashbroken "$1" restorefile aptarchive/dists/unstable/main/binary-i386/Packages breakfile aptarchive/dists/unstable/main/source/Sources - testfailure aptget update - testfileequal "$1" "$(listcurrentlistsdirectory)" + onehashbroken "$1" restorefile aptarchive/dists/unstable/main/source/Sources + + rm -rf aptarchive/dists + cp -a aptarchive/dists.good aptarchive/dists } testsetup() { msgmsg 'Test with no initial data over' "$1" - redatereleasefiles 'now' rm -rf rootdir/var/lib/apt/lists mkdir -p rootdir/var/lib/apt/lists/partial listcurrentlistsdirectory > listsdir.lst @@ -60,7 +73,6 @@ testsetup() { rm -rf rootdir/var/lib/apt/lists testsuccess aptget update -o Debug::pkgAcquire::Worker=1 listcurrentlistsdirectory > listsdir.lst - redatereleasefiles '+1hour' testrun 'listsdir.lst' } diff --git a/test/integration/test-cve-2013-1051-InRelease-parsing b/test/integration/test-cve-2013-1051-InRelease-parsing index e38e40cc9..d99174553 100755 --- a/test/integration/test-cve-2013-1051-InRelease-parsing +++ b/test/integration/test-cve-2013-1051-InRelease-parsing @@ -39,10 +39,15 @@ sed -i '/^-----BEGIN PGP SIGNATURE-----/,/^-----END PGP SIGNATURE-----/ s/^$/ / cat aptarchive/dists/stable/Release >> aptarchive/dists/stable/InRelease touch -d '+1hour' aptarchive/dists/stable/InRelease -# ensure the update fails -# useful for debugging to add "-o Debug::pkgAcquire::auth=true" -msgtest 'apt-get update for should fail with the modified' 'InRelease' -aptget update 2>&1 | grep -E -q '(Writing more data than expected|Hash Sum mismatch)' > /dev/null && msgpass || msgfail +# ensure the update doesn't load bad data as good data +# Note that we will pick up the InRelease itself as we download no other +# indexes which would trigger a hashsum mismatch, but we ignore the 'bad' +# part of the InRelease +listcurrentlistsdirectory | sed '/_InRelease/ d' > listsdir.lst +msgtest 'apt-get update should ignore unsigned data in the' 'InRelease' +testsuccessequal "Get:1 http://localhost:8080 stable InRelease [$(stat -c%s aptarchive/dists/stable/InRelease) B] +Reading package lists..." --nomsg aptget update +testfileequal './listsdir.lst' "$(listcurrentlistsdirectory | sed '/_InRelease/ d')" # ensure there is no package testfailureequal 'Reading package lists... -- cgit v1.2.3-70-g09d2 From 59148d9630bbbd53c6aa10da0fcdbd579797502a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 10 Jun 2015 19:22:41 +0200 Subject: abstract the code to iterate over all targets a bit We have two places in the code which need to iterate over targets and do certain things with it. The first one is actually creating these targets for download and the second instance pepares certain targets for reading. Git-Dch: Ignore --- apt-pkg/deb/debmetaindex.cc | 197 +++++++++++---------- test/integration/framework | 7 +- test/integration/test-apt-acquire-additional-files | 33 ++++ 3 files changed, 142 insertions(+), 95 deletions(-) (limited to 'test/integration/framework') diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 8fef05ab0..c35f3b0a4 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -90,10 +90,11 @@ debReleaseIndex::~debReleaseIndex() { delete *S; } -vector * debReleaseIndex::ComputeIndexTargets() const +template +void foreachTarget(std::string const URI, std::string const Dist, + std::map > const &ArchEntries, + CallC Call) { - vector * IndexTargets = new vector ; - bool const flatArchive = (Dist[Dist.length() - 1] == '/'); std::string baseURI = URI; if (flatArchive) @@ -108,7 +109,7 @@ vector * debReleaseIndex::ComputeIndexTargets() const std::vector lang = APT::Configuration::getLanguages(true); if (lang.empty()) lang.push_back("none"); - map >::const_iterator const src = ArchEntries.find("source"); + map >::const_iterator const src = ArchEntries.find("source"); if (src != ArchEntries.end()) { std::vector const targets = _config->FindVector("APT::Acquire::Targets::deb-src", "", true); @@ -123,8 +124,8 @@ vector * debReleaseIndex::ComputeIndexTargets() const if (URI.empty()) continue; - vector const SectionEntries = src->second; - for (vector::const_iterator I = SectionEntries.begin(); + vector const SectionEntries = src->second; + for (vector::const_iterator I = SectionEntries.begin(); I != SectionEntries.end(); ++I) { for (vector::const_iterator l = lang.begin(); l != lang.end(); ++l) @@ -139,27 +140,7 @@ vector * debReleaseIndex::ComputeIndexTargets() const { "$(LANGUAGE)", &(*l) }, { NULL, NULL } }; - std::string const name = SubstVar(URI, subst); - IndexTarget * Target; - if (IsOptional == true) - { - Target = new OptionalIndexTarget( - name, - SubstVar(ShortDesc, subst), - SubstVar(LongDesc, subst), - baseURI + name - ); - } - else - { - Target = new IndexTarget( - name, - SubstVar(ShortDesc, subst), - SubstVar(LongDesc, subst), - baseURI + name - ); - } - IndexTargets->push_back(Target); + Call(baseURI, *T, URI, ShortDesc, LongDesc, IsOptional, subst); if (URI.find("$(LANGUAGE)") == std::string::npos) break; @@ -171,10 +152,6 @@ vector * debReleaseIndex::ComputeIndexTargets() const } } - // Only source release - if (IndexTargets->empty() == false && ArchEntries.size() == 1) - return IndexTargets; - std::vector const targets = _config->FindVector("APT::Acquire::Targets::deb", "", true); for (std::vector::const_iterator T = targets.begin(); T != targets.end(); ++T) { @@ -187,13 +164,13 @@ vector * debReleaseIndex::ComputeIndexTargets() const if (URI.empty()) continue; - for (map >::const_iterator a = ArchEntries.begin(); + for (map >::const_iterator a = ArchEntries.begin(); a != ArchEntries.end(); ++a) { if (a->first == "source") continue; - for (vector ::const_iterator I = a->second.begin(); + for (vector ::const_iterator I = a->second.begin(); I != a->second.end(); ++I) { for (vector::const_iterator l = lang.begin(); l != lang.end(); ++l) @@ -209,27 +186,7 @@ vector * debReleaseIndex::ComputeIndexTargets() const { "$(ARCHITECTURE)", &(a->first) }, { NULL, NULL } }; - std::string const name = SubstVar(URI, subst); - IndexTarget * Target; - if (IsOptional == true) - { - Target = new OptionalIndexTarget( - name, - SubstVar(ShortDesc, subst), - SubstVar(LongDesc, subst), - baseURI + name - ); - } - else - { - Target = new IndexTarget( - name, - SubstVar(ShortDesc, subst), - SubstVar(LongDesc, subst), - baseURI + name - ); - } - IndexTargets->push_back(Target); + Call(baseURI, *T, URI, ShortDesc, LongDesc, IsOptional, subst); if (URI.find("$(LANGUAGE)") == std::string::npos) break; @@ -243,9 +200,51 @@ vector * debReleaseIndex::ComputeIndexTargets() const break; } } +} + + +struct ComputeIndexTargetsClass +{ + vector * const IndexTargets; + + void operator()(std::string const &baseURI, std::string const &/*TargetName*/, + std::string const &URI, std::string const &ShortDesc, std::string const &LongDesc, + bool const IsOptional, struct SubstVar const * const subst) + { + std::string const name = SubstVar(URI, subst); + IndexTarget * Target; + if (IsOptional == true) + { + Target = new OptionalIndexTarget( + name, + SubstVar(ShortDesc, subst), + SubstVar(LongDesc, subst), + baseURI + name + ); + } + else + { + Target = new IndexTarget( + name, + SubstVar(ShortDesc, subst), + SubstVar(LongDesc, subst), + baseURI + name + ); + } + IndexTargets->push_back(Target); + } - return IndexTargets; + ComputeIndexTargetsClass() : IndexTargets(new vector ) {} +}; + +vector * debReleaseIndex::ComputeIndexTargets() const +{ + ComputeIndexTargetsClass comp; + foreachTarget(URI, Dist, ArchEntries, comp); + return comp.IndexTargets; } + + /*}}}*/ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const { @@ -303,45 +302,55 @@ bool debReleaseIndex::IsTrusted() const return FileExists(VerifiedSigFile); } -vector *debReleaseIndex::GetIndexFiles() { - if (Indexes != NULL) - return Indexes; - - Indexes = new vector ; - map >::const_iterator const src = ArchEntries.find("source"); - if (src != ArchEntries.end()) { - vector const SectionEntries = src->second; - for (vector::const_iterator I = SectionEntries.begin(); - I != SectionEntries.end(); ++I) - Indexes->push_back(new debSourcesIndex (URI, Dist, (*I)->Section, IsTrusted())); - } - - // Only source release - if (Indexes->empty() == false && ArchEntries.size() == 1) - return Indexes; - - std::vector const lang = APT::Configuration::getLanguages(true); - map > sections; - for (map >::const_iterator a = ArchEntries.begin(); - a != ArchEntries.end(); ++a) { - if (a->first == "source") - continue; - for (vector::const_iterator I = a->second.begin(); - I != a->second.end(); ++I) { - Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted(), a->first)); - sections[(*I)->Section].insert(lang.begin(), lang.end()); - } - } - - for (map >::const_iterator s = sections.begin(); - s != sections.end(); ++s) - for (set::const_iterator l = s->second.begin(); - l != s->second.end(); ++l) { - if (*l == "none") continue; - Indexes->push_back(new debTranslationsIndex(URI,Dist,s->first,(*l).c_str())); - } - - return Indexes; +struct GetIndexFilesClass +{ + vector * const Indexes; + std::string const URI; + std::string const Release; + bool const IsTrusted; + + void operator()(std::string const &/*baseURI*/, std::string const &TargetName, + std::string const &/*URI*/, std::string const &/*ShortDesc*/, std::string const &/*LongDesc*/, + bool const /*IsOptional*/, struct SubstVar const * const subst) + { + if (TargetName == "Packages") + { + Indexes->push_back(new debPackagesIndex( + URI, + Release, + SubstVar("$(COMPONENT)", subst), + IsTrusted, + SubstVar("$(ARCHITECTURE)", subst) + )); + } + else if (TargetName == "Sources") + Indexes->push_back(new debSourcesIndex( + URI, + Release, + SubstVar("$(COMPONENT)", subst), + IsTrusted + )); + else if (TargetName == "Translations") + Indexes->push_back(new debTranslationsIndex( + URI, + Release, + SubstVar("$(COMPONENT)", subst), + SubstVar("$(LANGUAGE)", subst) + )); + } + + GetIndexFilesClass(std::string const &URI, std::string const &Release, bool const IsTrusted) : + Indexes(new vector ), URI(URI), Release(Release), IsTrusted(IsTrusted) {} +}; + +std::vector *debReleaseIndex::GetIndexFiles() +{ + if (Indexes != NULL) + return Indexes; + + GetIndexFilesClass comp(URI, Dist, IsTrusted()); + foreachTarget(URI, Dist, ArchEntries, comp); + return Indexes = comp.Indexes; } void debReleaseIndex::PushSectionEntry(vector const &Archs, const debSectionEntry *Entry) { diff --git a/test/integration/framework b/test/integration/framework index 56c4a1216..110758e82 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -1531,6 +1531,11 @@ aptautotest() { } aptautotest_aptget_update() { + local TESTCALL="$1" + while [ -n "$2" ]; do + if [ "$2" = '--print-uris' ]; then return; fi # simulation mode + shift + done if ! test -d "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists"; then return; fi testfilestats "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:755" testfilestats "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:755" @@ -1538,7 +1543,7 @@ aptautotest_aptget_update() { for file in $(find "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists" -type f ! -name 'lock'); do testfilestats "$file" '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644" done - if [ "$1" = 'testsuccess' ]; then + if [ "$TESTCALL" = 'testsuccess' ]; then # 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 diff --git a/test/integration/test-apt-acquire-additional-files b/test/integration/test-apt-acquire-additional-files index 150a50980..0e59233e9 100755 --- a/test/integration/test-apt-acquire-additional-files +++ b/test/integration/test-apt-acquire-additional-files @@ -6,6 +6,9 @@ TESTDIR=$(readlink -f $(dirname $0)) setupenvironment configarchitecture 'amd64' + +# note that in --print-uri we talk about .bz2 because that is the default. +# This doesn't mean it is actually attempt to download it. configcompression '.' 'gz' buildsimplenativepackage 'foo' 'amd64' '1' 'unstable' @@ -13,6 +16,11 @@ buildsimplenativepackage 'foo' 'amd64' '1' 'unstable' setupaptarchive --no-update changetowebserver +testequal "'http://localhost:8080/dists/unstable/InRelease' localhost:8080_dists_unstable_InRelease 0 +'http://localhost:8080/dists/unstable/main/source/Sources.bz2' localhost:8080_dists_unstable_main_source_Sources 0 +'http://localhost:8080/dists/unstable/main/binary-amd64/Packages.bz2' localhost:8080_dists_unstable_main_binary-amd64_Packages 0 +'http://localhost:8080/dists/unstable/main/i18n/Translation-en.bz2' localhost:8080_dists_unstable_main_i18n_Translation-en 0 " aptget update --print-uris + testsuccessequal "Get:1 http://localhost:8080 unstable InRelease [$(stat -c%s aptarchive/dists/unstable/InRelease) B] Get:2 http://localhost:8080 unstable/main Sources [$(stat -c%s aptarchive/dists/unstable/main/source/Sources.gz) B] Get:3 http://localhost:8080 unstable/main amd64 Packages [$(stat -c%s aptarchive/dists/unstable/main/binary-amd64/Packages.gz) B] @@ -29,6 +37,12 @@ APT::Acquire::Targets::deb::Contents { }; EOF +testequal "'http://localhost:8080/dists/unstable/InRelease' localhost:8080_dists_unstable_InRelease 0 +'http://localhost:8080/dists/unstable/main/source/Sources.bz2' localhost:8080_dists_unstable_main_source_Sources 0 +'http://localhost:8080/dists/unstable/main/binary-amd64/Packages.bz2' localhost:8080_dists_unstable_main_binary-amd64_Packages 0 +'http://localhost:8080/dists/unstable/main/i18n/Translation-en.bz2' localhost:8080_dists_unstable_main_i18n_Translation-en 0 +'http://localhost:8080/dists/unstable/main/Contents-amd64.bz2' localhost:8080_dists_unstable_main_Contents-amd64 0 " aptget update --print-uris + testsuccessequal "Hit http://localhost:8080 unstable InRelease Get:1 http://localhost:8080 unstable/main amd64 Contents [$(stat -c%s aptarchive/dists/unstable/main/Contents-amd64.gz) B] Reading package lists..." aptget update @@ -46,9 +60,28 @@ APT::Acquire::Targets::deb::Contents { }; EOF +# the last line is utter bogus of course, but how should apt know… +testequal "'http://localhost:8080/dists/unstable/InRelease' localhost:8080_dists_unstable_InRelease 0 +'http://localhost:8080/dists/unstable/main/source/Sources.bz2' localhost:8080_dists_unstable_main_source_Sources 0 +'http://localhost:8080/dists/unstable/main/binary-amd64/Packages.bz2' localhost:8080_dists_unstable_main_binary-amd64_Packages 0 +'http://localhost:8080/dists/unstable/main/i18n/Translation-en.bz2' localhost:8080_dists_unstable_main_i18n_Translation-en 0 +'http://localhost:8080/dists/unstable/main/Contents-amd64.gz.bz2' localhost:8080_dists_unstable_main_Contents-amd64.gz 0 " aptget update --print-uris + testsuccessequal "Hit http://localhost:8080 unstable InRelease Get:1 http://localhost:8080 unstable/main amd64 Contents.gz [$(stat -c%s aptarchive/dists/unstable/main/Contents-amd64.gz) B] Reading package lists..." aptget update testequal 'rootdir/var/lib/apt/lists/localhost:8080_dists_unstable_main_Contents-amd64.gz' find rootdir/var/lib/apt/lists -name '*Contents*' testsuccess cmp 'rootdir/var/lib/apt/lists/localhost:8080_dists_unstable_main_Contents-amd64.gz' 'aptarchive/dists/unstable/main/Contents-amd64.gz' + +rm -f rootdir/etc/apt/apt.conf.d/content-target.conf + +testequal "'http://localhost:8080/dists/unstable/InRelease' localhost:8080_dists_unstable_InRelease 0 +'http://localhost:8080/dists/unstable/main/source/Sources.bz2' localhost:8080_dists_unstable_main_source_Sources 0 +'http://localhost:8080/dists/unstable/main/binary-amd64/Packages.bz2' localhost:8080_dists_unstable_main_binary-amd64_Packages 0 +'http://localhost:8080/dists/unstable/main/i18n/Translation-en.bz2' localhost:8080_dists_unstable_main_i18n_Translation-en 0 " aptget update --print-uris + +testsuccessequal "Hit http://localhost:8080 unstable InRelease +Reading package lists..." aptget update + +testempty find rootdir/var/lib/apt/lists -name '*Contents*' -- cgit v1.2.3-70-g09d2 From b07aeb1a6e24825e534167a737043441e871de9f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 12 Jun 2015 02:08:53 +0200 Subject: store Release files data in the Cache We used to read the Release file for each Packages file and store the data in the PackageFile struct even through potentially many Packages (and Translation-*) files could use the same data. The point of the exercise isn't the duplicated data through. Having the Release files as first-class citizens in the Cache allows us to properly track their state as well as allows us to use the information also for files which aren't in the cache, but where we know to which Release file they belong (Sources are an example for this). This modifies the pkgCache structs, especially the PackagesFile struct which depending on how libapt users access the data in these structs can mean huge breakage or no visible change. As a single data point: aptitude seems to be fine with this. Even if there is breakage it is trivial to fix in a backportable way while avoiding breakage for everyone would be a huge pain for us. Note that not all PackageFile structs have a corresponding ReleaseFile. In particular the dpkg/status file as well as *.deb files have not. As these have only a Archive property need, the Component property takes over this duty and the ReleaseFile remains zero. This is also the reason why it isn't needed nor particularily recommended to change from PackagesFile to ReleaseFile blindly. Sticking with the earlier is usually the better option. --- apt-pkg/acquire-item.cc | 6 +- apt-pkg/cacheiterators.h | 46 ++++++- apt-pkg/clean.cc | 2 +- apt-pkg/deb/debindexfile.cc | 42 ++----- apt-pkg/deb/debindexfile.h | 1 - apt-pkg/deb/deblistparser.cc | 37 ------ apt-pkg/deb/deblistparser.h | 6 +- apt-pkg/deb/debmetaindex.cc | 124 ++++++++++++++++++- apt-pkg/deb/debmetaindex.h | 6 + apt-pkg/deb/dpkgpm.cc | 4 +- apt-pkg/depcache.cc | 6 +- apt-pkg/edsp.cc | 2 +- apt-pkg/edsp/edspindexfile.cc | 5 +- apt-pkg/edsp/edsplistparser.cc | 4 +- apt-pkg/edsp/edsplistparser.h | 4 +- apt-pkg/metaindex.cc | 17 +++ apt-pkg/metaindex.h | 6 + apt-pkg/pkgcache.cc | 77 ++++++++---- apt-pkg/pkgcache.h | 75 ++++++++++-- apt-pkg/pkgcachegen.cc | 226 +++++++++++++++++++++++++++-------- apt-pkg/pkgcachegen.h | 10 +- apt-pkg/policy.cc | 15 ++- apt-pkg/versionmatch.cc | 45 +++---- apt-pkg/versionmatch.h | 4 +- cmdline/apt-cache.cc | 11 +- test/integration/framework | 9 +- test/integration/test-policy-pinning | 2 +- 27 files changed, 573 insertions(+), 219 deletions(-) (limited to 'test/integration/framework') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index d4191f00e..d6e9ccbe0 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -2568,7 +2568,7 @@ pkgAcqArchive::pkgAcqArchive(pkgAcquire * const Owner,pkgSourceList * const Sour // Skip not source sources, they do not have file fields. for (; Vf.end() == false; ++Vf) { - if ((Vf.File()->Flags & pkgCache::Flag::NotSource) != 0) + if (Vf.File().Flagged(pkgCache::Flag::NotSource)) continue; break; } @@ -2636,14 +2636,14 @@ bool pkgAcqArchive::QueueNext() { pkgCache::PkgFileIterator const PkgF = Vf.File(); // Ignore not source sources - if ((PkgF->Flags & pkgCache::Flag::NotSource) != 0) + if (PkgF.Flagged(pkgCache::Flag::NotSource)) continue; // Try to cross match against the source list pkgIndexFile *Index; if (Sources->FindIndex(PkgF, Index) == false) continue; - LocalSource = (PkgF->Flags & pkgCache::Flag::LocalSource) == pkgCache::Flag::LocalSource; + LocalSource = PkgF.Flagged(pkgCache::Flag::LocalSource); // only try to get a trusted package from another source if that source // is also trusted diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index fe798799c..301da6fc4 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -367,27 +367,61 @@ class pkgCache::PrvIterator : public Iterator { } }; /*}}}*/ -// Package file /*{{{*/ -class pkgCache::PkgFileIterator : public Iterator { +// Release file /*{{{*/ +class pkgCache::RlsFileIterator : public Iterator { protected: - inline PackageFile* OwnerPointer() const { - return (Owner != 0) ? Owner->PkgFileP : 0; + inline ReleaseFile* OwnerPointer() const { + return (Owner != 0) ? Owner->RlsFileP : 0; } public: // Iteration - void operator ++(int) {if (S != Owner->PkgFileP) S = Owner->PkgFileP + S->NextFile;} + void operator ++(int) {if (S != Owner->RlsFileP) S = Owner->RlsFileP + S->NextFile;} inline void operator ++() {operator ++(0);} // Accessors inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;} inline const char *Archive() const {return S->Archive == 0?0:Owner->StrP + S->Archive;} - inline const char *Component() const {return S->Component == 0?0:Owner->StrP + S->Component;} inline const char *Version() const {return S->Version == 0?0:Owner->StrP + S->Version;} inline const char *Origin() const {return S->Origin == 0?0:Owner->StrP + S->Origin;} inline const char *Codename() const {return S->Codename ==0?0:Owner->StrP + S->Codename;} inline const char *Label() const {return S->Label == 0?0:Owner->StrP + S->Label;} inline const char *Site() const {return S->Site == 0?0:Owner->StrP + S->Site;} + inline bool Flagged(pkgCache::Flag::ReleaseFileFlags const flag) const {return (S->Flags & flag) == flag; } + + bool IsOk(); + std::string RelStr(); + + // Constructors + inline RlsFileIterator() : Iterator() {} + inline RlsFileIterator(pkgCache &Owner) : Iterator(Owner, Owner.RlsFileP) {} + inline RlsFileIterator(pkgCache &Owner,ReleaseFile *Trg) : Iterator(Owner, Trg) {} +}; + /*}}}*/ +// Package file /*{{{*/ +class pkgCache::PkgFileIterator : public Iterator { + protected: + inline PackageFile* OwnerPointer() const { + return (Owner != 0) ? Owner->PkgFileP : 0; + } + + public: + // Iteration + void operator ++(int) {if (S != Owner->PkgFileP) S = Owner->PkgFileP + S->NextFile;} + inline void operator ++() {operator ++(0);} + + // Accessors + inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;} + inline pkgCache::RlsFileIterator ReleaseFile() const {return RlsFileIterator(*Owner, Owner->RlsFileP + S->Release);} + inline const char *Archive() const {return S->Release == 0 ? Component() : ReleaseFile().Archive();} + inline const char *Version() const {return S->Release == 0 ? NULL : ReleaseFile().Version();} + inline const char *Origin() const {return S->Release == 0 ? NULL : ReleaseFile().Origin();} + inline const char *Codename() const {return S->Release == 0 ? NULL : ReleaseFile().Codename();} + inline const char *Label() const {return S->Release == 0 ? NULL : ReleaseFile().Label();} + inline const char *Site() const {return S->Release == 0 ? NULL : ReleaseFile().Site();} + inline bool Flagged(pkgCache::Flag::ReleaseFileFlags const flag) const {return S->Release== 0 ? false : ReleaseFile().Flagged(flag);} + inline bool Flagged(pkgCache::Flag::PkgFFlags const flag) const {return (S->Flags & flag) == flag;} + inline const char *Component() const {return S->Component == 0?0:Owner->StrP + S->Component;} inline const char *Architecture() const {return S->Architecture == 0?0:Owner->StrP + S->Architecture;} inline const char *IndexType() const {return S->IndexType == 0?0:Owner->StrP + S->IndexType;} diff --git a/apt-pkg/clean.cc b/apt-pkg/clean.cc index 6edce5b6d..0fca60ba9 100644 --- a/apt-pkg/clean.cc +++ b/apt-pkg/clean.cc @@ -106,7 +106,7 @@ bool pkgArchiveCleaner::Go(std::string Dir,pkgCache &Cache) J.end() == false; ++J) { if (CleanInstalled == true && - (J.File()->Flags & pkgCache::Flag::NotSource) != 0) + J.File().Flagged(pkgCache::Flag::NotSource)) continue; IsFetchable = true; break; diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index 7aad65c0e..3a79cbc58 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -128,7 +128,7 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const if (Dist.empty()) Dist = "/"; ::URI Tmp(URI); - if (Gen.SelectFile(PackageFile,Tmp.Host,*this) == false) + if (Gen.SelectFile(PackageFile, *this, Target.Option(IndexTarget::COMPONENT)) == false) return _error->Error("Problem with SelectFile %s",PackageFile.c_str()); // Store the IMS information @@ -136,31 +136,10 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const pkgCacheGenerator::Dynamic DynFile(File); File->Size = Pkg.FileSize(); File->mtime = Pkg.ModificationTime(); - + if (Gen.MergeList(Parser) == false) return _error->Error("Problem with MergeList %s",PackageFile.c_str()); - // Check the release file - string ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("InRelease"); - bool releaseExists = false; - if (FileExists(ReleaseFile) == true) - releaseExists = true; - else - ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("Release"); - - if (releaseExists == true || FileExists(ReleaseFile) == true) - { - FileFd Rel; - // Beware: The 'Release' file might be clearsigned in case the - // signature for an 'InRelease' file couldn't be checked - if (OpenMaybeClearSignedFile(ReleaseFile, Rel) == false) - return false; - - if (_error->PendingError() == true) - return false; - Parser.LoadReleaseInfo(File, Rel, Target.Option(IndexTarget::COMPONENT)); - } - return true; } /*}}}*/ @@ -221,17 +200,17 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const debTranslationsParser TransParser(&Trans); if (_error->PendingError() == true) return false; - + if (Prog != NULL) Prog->SubProgress(0, Target.Description); - if (Gen.SelectFile(TranslationFile,string(),*this) == false) + if (Gen.SelectFile(TranslationFile, *this, Target.Option(IndexTarget::COMPONENT), pkgCache::Flag::NotSource) == false) return _error->Error("Problem with SelectFile %s",TranslationFile.c_str()); // Store the IMS information pkgCache::PkgFileIterator TransFile = Gen.GetCurFile(); TransFile->Size = Trans.FileSize(); TransFile->mtime = Trans.ModificationTime(); - + if (Gen.MergeList(TransParser) == false) return _error->Error("Problem with MergeList %s",TranslationFile.c_str()); } @@ -305,18 +284,17 @@ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const if (Prog != NULL) Prog->SubProgress(0,File); - if (Gen.SelectFile(File,string(),*this,pkgCache::Flag::NotSource) == false) + if (Gen.SelectFile(File, *this, "now", pkgCache::Flag::NotSource) == false) return _error->Error("Problem with SelectFile %s",File.c_str()); // Store the IMS information pkgCache::PkgFileIterator CFile = Gen.GetCurFile(); + pkgCacheGenerator::Dynamic DynFile(CFile); CFile->Size = Pkg.FileSize(); CFile->mtime = Pkg.ModificationTime(); - map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::MIXED, "now"); - CFile->Archive = storage; - + if (Gen.MergeList(Parser) == false) - return _error->Error("Problem with MergeList %s",File.c_str()); + return _error->Error("Problem with MergeList %s",File.c_str()); return true; } /*}}}*/ @@ -431,7 +409,7 @@ bool debDebPkgFileIndex::Merge(pkgCacheGenerator& Gen, OpProgress* Prog) const // and give it to the list parser debDebFileParser Parser(DebControl, DebFile); - if(Gen.SelectFile(DebFile, "local", *this, pkgCache::Flag::LocalSource) == false) + if(Gen.SelectFile(DebFile, *this, "now", pkgCache::Flag::LocalSource) == false) return _error->Error("Problem with SelectFile %s", DebFile.c_str()); pkgCache::PkgFileIterator File = Gen.GetCurFile(); diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h index dd3f212b2..6b8c78e5a 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@ -45,7 +45,6 @@ class APT_HIDDEN debStatusIndex : public pkgIndexFile virtual bool HasPackages() const {return true;}; virtual unsigned long Size() const; virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; - bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog, unsigned long const Flag) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; debStatusIndex(std::string File); diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index b80b57bc4..c5e77b0ff 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -951,43 +951,6 @@ bool debListParser::Step() return false; } /*}}}*/ -// ListParser::LoadReleaseInfo - Load the release information /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, - FileFd &File, string component) -{ - // apt-secure does no longer download individual (per-section) Release - // file. to provide Component pinning we use the section name now - map_stringitem_t const storage = StoreString(pkgCacheGenerator::MIXED, component); - FileI->Component = storage; - - pkgTagFile TagFile(&File, File.Size()); - pkgTagSection Section; - if (_error->PendingError() == true || TagFile.Step(Section) == false) - return false; - - std::string data; - #define APT_INRELEASE(TYPE, TAG, STORE) \ - data = Section.FindS(TAG); \ - if (data.empty() == false) \ - { \ - map_stringitem_t const storage = StoreString(pkgCacheGenerator::TYPE, data); \ - STORE = storage; \ - } - APT_INRELEASE(MIXED, "Suite", FileI->Archive) - APT_INRELEASE(MIXED, "Component", FileI->Component) - APT_INRELEASE(VERSIONNUMBER, "Version", FileI->Version) - APT_INRELEASE(MIXED, "Origin", FileI->Origin) - APT_INRELEASE(MIXED, "Codename", FileI->Codename) - APT_INRELEASE(MIXED, "Label", FileI->Label) - #undef APT_INRELEASE - Section.FindFlag("NotAutomatic", FileI->Flags, pkgCache::Flag::NotAutomatic); - Section.FindFlag("ButAutomaticUpgrades", FileI->Flags, pkgCache::Flag::ButAutomaticUpgrades); - - return !_error->PendingError(); -} - /*}}}*/ // ListParser::GetPrio - Convert the priority from a string /*{{{*/ // --------------------------------------------------------------------- /* */ diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 6279d8399..420d5ff08 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -80,9 +80,9 @@ class APT_HIDDEN debListParser : public pkgCacheGenerator::ListParser virtual map_filesize_t Size() {return Section.size();}; virtual bool Step(); - - bool LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,FileFd &File, - std::string section); + + bool LoadReleaseInfo(pkgCache::RlsFileIterator &FileI,FileFd &File, + std::string const §ion); APT_PUBLIC static const char *ParseDepends(const char *Start,const char *Stop, std::string &Package,std::string &Ver,unsigned int &Op); diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 8e4c2be2d..994b95849 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -10,10 +11,12 @@ #include #include #include -#include #include +#include +#include +#include +#include -#include #include #include #include @@ -21,6 +24,11 @@ #include #include +#include +#include +#include +#include + using namespace std; string debReleaseIndex::MetaIndexInfo(const char *Type) const @@ -37,6 +45,10 @@ string debReleaseIndex::MetaIndexInfo(const char *Type) const Info += Type; return Info; } +std::string debReleaseIndex::Describe() const +{ + return MetaIndexInfo("Release"); +} string debReleaseIndex::MetaIndexFile(const char *Type) const { @@ -339,6 +351,114 @@ debReleaseIndex::debSectionEntry::debSectionEntry (string const &Section, bool const &IsSrc): Section(Section), IsSrc(IsSrc) {} +static bool ReleaseFileName(debReleaseIndex const * const That, std::string &ReleaseFile) +{ + ReleaseFile = That->MetaIndexFile("InRelease"); + bool releaseExists = false; + if (FileExists(ReleaseFile) == true) + releaseExists = true; + else + { + ReleaseFile = That->MetaIndexFile("Release"); + if (FileExists(ReleaseFile)) + releaseExists = true; + } + return releaseExists; +} + +bool debReleaseIndex::Merge(pkgCacheGenerator &Gen,OpProgress * /*Prog*/) const/*{{{*/ +{ + std::string ReleaseFile; + bool const releaseExists = ReleaseFileName(this, ReleaseFile); + + ::URI Tmp(URI); + if (Gen.SelectReleaseFile(ReleaseFile, Tmp.Host) == false) + return _error->Error("Problem with SelectReleaseFile %s", ReleaseFile.c_str()); + + if (releaseExists == false) + return true; + + FileFd Rel; + // Beware: The 'Release' file might be clearsigned in case the + // signature for an 'InRelease' file couldn't be checked + if (OpenMaybeClearSignedFile(ReleaseFile, Rel) == false) + return false; + if (_error->PendingError() == true) + return false; + + // Store the IMS information + pkgCache::RlsFileIterator File = Gen.GetCurRlsFile(); + pkgCacheGenerator::Dynamic DynFile(File); + // Rel can't be used as this is potentially a temporary file + struct stat Buf; + if (stat(ReleaseFile.c_str(), &Buf) != 0) + return _error->Errno("fstat", "Unable to stat file %s", ReleaseFile.c_str()); + File->Size = Buf.st_size; + File->mtime = Buf.st_mtime; + + pkgTagFile TagFile(&Rel, Rel.Size()); + pkgTagSection Section; + if (_error->PendingError() == true || TagFile.Step(Section) == false) + return false; + + std::string data; + #define APT_INRELEASE(TYPE, TAG, STORE) \ + data = Section.FindS(TAG); \ + if (data.empty() == false) \ + { \ + map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::TYPE, data); \ + STORE = storage; \ + } + APT_INRELEASE(MIXED, "Suite", File->Archive) + APT_INRELEASE(VERSIONNUMBER, "Version", File->Version) + APT_INRELEASE(MIXED, "Origin", File->Origin) + APT_INRELEASE(MIXED, "Codename", File->Codename) + APT_INRELEASE(MIXED, "Label", File->Label) + #undef APT_INRELEASE + Section.FindFlag("NotAutomatic", File->Flags, pkgCache::Flag::NotAutomatic); + Section.FindFlag("ButAutomaticUpgrades", File->Flags, pkgCache::Flag::ButAutomaticUpgrades); + + return !_error->PendingError(); +} + /*}}}*/ +// ReleaseIndex::FindInCache - Find this index /*{{{*/ +pkgCache::RlsFileIterator debReleaseIndex::FindInCache(pkgCache &Cache) const +{ + std::string ReleaseFile; + bool const releaseExists = ReleaseFileName(this, ReleaseFile); + + pkgCache::RlsFileIterator File = Cache.RlsFileBegin(); + for (; File.end() == false; ++File) + { + if (File->FileName == 0 || ReleaseFile != File.FileName()) + continue; + + // empty means the file does not exist by "design" + if (releaseExists == false && File->Size == 0) + return File; + + struct stat St; + if (stat(File.FileName(),&St) != 0) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "ReleaseIndex::FindInCache - stat failed on " << File.FileName() << std::endl; + return pkgCache::RlsFileIterator(Cache); + } + if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "ReleaseIndex::FindInCache - size (" << St.st_size << " <> " << File->Size + << ") or mtime (" << St.st_mtime << " <> " << File->mtime + << ") doesn't match for " << File.FileName() << std::endl; + return pkgCache::RlsFileIterator(Cache); + } + return File; + } + + return File; +} + /*}}}*/ + class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type { protected: diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h index 0b1b08432..7e9942710 100644 --- a/apt-pkg/deb/debmetaindex.h +++ b/apt-pkg/deb/debmetaindex.h @@ -20,6 +20,8 @@ class pkgAcquire; class pkgIndexFile; class debDebPkgFileIndex; class IndexTarget; +class pkgCacheGenerator; +class OpProgress; class APT_HIDDEN debReleaseIndex : public metaIndex { public: @@ -48,6 +50,10 @@ class APT_HIDDEN debReleaseIndex : public metaIndex { virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const; virtual std::vector GetIndexTargets() const; + virtual std::string Describe() const; + virtual pkgCache::RlsFileIterator FindInCache(pkgCache &Cache) const; + virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; + std::string MetaIndexInfo(const char *Type) const; std::string MetaIndexFile(const char *Types) const; std::string MetaIndexURI(const char *Type) const; diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index a7a66c75d..6ee939edd 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -205,8 +205,10 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg) for (Ver = Pkg.VersionList(); Ver.end() == false; ++Ver) for (pkgCache::VerFileIterator Vf = Ver.FileList(); Vf.end() == false; ++Vf) for (pkgCache::PkgFileIterator F = Vf.File(); F.end() == false; ++F) - if (F->Archive != 0 && strcmp(F.Archive(), "now") == 0) + { + if (F.Archive() != 0 && strcmp(F.Archive(), "now") == 0) return Ver; + } return Ver; } /*}}}*/ diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index b73c336db..36e1ac9ec 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1685,13 +1685,13 @@ pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator const &Pk for (VerFileIterator J = I.FileList(); J.end() == false; ++J) { - if ((J.File()->Flags & Flag::NotSource) != 0) + if (J.File().Flagged(Flag::NotSource)) continue; /* Stash the highest version of a not-automatic source, we use it if there is nothing better */ - if ((J.File()->Flags & Flag::NotAutomatic) != 0 || - (J.File()->Flags & Flag::ButAutomaticUpgrades) != 0) + if (J.File().Flagged(Flag::NotAutomatic) || + J.File().Flagged(Flag::ButAutomaticUpgrades)) { if (Last.end() == true) Last = I; diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index 3c6a7e30f..41cc2cdfe 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -129,7 +129,7 @@ void EDSP::WriteScenarioVersion(pkgDepCache &Cache, FILE* output, pkgCache::PkgI signed short const p = Cache.GetPolicy().GetPriority(File); if (Pin < p) Pin = p; - if ((File->Flags & pkgCache::Flag::NotSource) != pkgCache::Flag::NotSource) { + if (File.Flagged(pkgCache::Flag::NotSource) == false) { string Release = File.RelStr(); if (!Release.empty()) Releases.insert(Release); diff --git a/apt-pkg/edsp/edspindexfile.cc b/apt-pkg/edsp/edspindexfile.cc index d00536362..43dd44a79 100644 --- a/apt-pkg/edsp/edspindexfile.cc +++ b/apt-pkg/edsp/edspindexfile.cc @@ -49,15 +49,14 @@ bool edspIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const if (Prog != NULL) Prog->SubProgress(0,File); - if (Gen.SelectFile(File,std::string(),*this) == false) + if (Gen.SelectFile(File, *this, "edsp") == false) return _error->Error("Problem with SelectFile %s",File.c_str()); // Store the IMS information pkgCache::PkgFileIterator CFile = Gen.GetCurFile(); + pkgCacheGenerator::Dynamic DynFile(CFile); CFile->Size = Pkg.FileSize(); CFile->mtime = Pkg.ModificationTime(); - map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::MIXED, "edsp::scenario"); - CFile->Archive = storage; if (Gen.MergeList(Parser) == false) return _error->Error("Problem with MergeList %s",File.c_str()); diff --git a/apt-pkg/edsp/edsplistparser.cc b/apt-pkg/edsp/edsplistparser.cc index 212dc7840..d62abe709 100644 --- a/apt-pkg/edsp/edsplistparser.cc +++ b/apt-pkg/edsp/edsplistparser.cc @@ -86,8 +86,8 @@ bool edspListParser::ParseStatus(pkgCache::PkgIterator &Pkg, } /*}}}*/ // ListParser::LoadReleaseInfo - Load the release information /*{{{*/ -APT_CONST bool edspListParser::LoadReleaseInfo(pkgCache::PkgFileIterator & /*FileI*/, - FileFd & /*File*/, std::string /*component*/) +APT_CONST bool edspListParser::LoadReleaseInfo(pkgCache::RlsFileIterator & /*FileI*/, + FileFd & /*File*/, std::string const &/*component*/) { return true; } diff --git a/apt-pkg/edsp/edsplistparser.h b/apt-pkg/edsp/edsplistparser.h index 86cd77606..abe2ef139 100644 --- a/apt-pkg/edsp/edsplistparser.h +++ b/apt-pkg/edsp/edsplistparser.h @@ -34,8 +34,8 @@ class APT_HIDDEN edspListParser : public debListParser virtual MD5SumValue Description_md5(); virtual unsigned short VersionHash(); - bool LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,FileFd &File, - std::string section); + bool LoadReleaseInfo(pkgCache::RlsFileIterator &FileI,FileFd &File, + std::string const §ion); edspListParser(FileFd *File, std::string const &Arch = ""); diff --git a/apt-pkg/metaindex.cc b/apt-pkg/metaindex.cc index 31a8ec009..35ab6c53b 100644 --- a/apt-pkg/metaindex.cc +++ b/apt-pkg/metaindex.cc @@ -1,4 +1,5 @@ // Include Files /*{{{*/ +#include #include #include @@ -22,6 +23,22 @@ std::string metaIndex::LocalFileName() const } #endif +std::string metaIndex::Describe() const +{ + return "Release"; +} + +pkgCache::RlsFileIterator metaIndex::FindInCache(pkgCache &Cache) const +{ + return pkgCache::RlsFileIterator(Cache); +} + +bool metaIndex::Merge(pkgCacheGenerator &Gen,OpProgress *) const +{ + return Gen.SelectReleaseFile("", ""); +} + + metaIndex::metaIndex(std::string const &URI, std::string const &Dist, char const * const Type) : Indexes(NULL), Type(Type), URI(URI), Dist(Dist), Trusted(false) diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h index 4e5de8be0..20c879a89 100644 --- a/apt-pkg/metaindex.h +++ b/apt-pkg/metaindex.h @@ -23,6 +23,8 @@ using std::string; class pkgAcquire; class IndexTarget; +class pkgCacheGenerator; +class OpProgress; class metaIndex { @@ -51,6 +53,10 @@ class metaIndex virtual std::vector *GetIndexFiles() = 0; virtual bool IsTrusted() const = 0; + virtual std::string Describe() const; + virtual pkgCache::RlsFileIterator FindInCache(pkgCache &Cache) const; + virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; + metaIndex(std::string const &URI, std::string const &Dist, char const * const Type); virtual ~metaIndex(); diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 864ae0f60..9fe382108 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -61,6 +61,7 @@ pkgCache::Header::Header() HeaderSz = sizeof(pkgCache::Header); GroupSz = sizeof(pkgCache::Group); PackageSz = sizeof(pkgCache::Package); + ReleaseFileSz = sizeof(pkgCache::ReleaseFile); PackageFileSz = sizeof(pkgCache::PackageFile); VersionSz = sizeof(pkgCache::Version); DescriptionSz = sizeof(pkgCache::Description); @@ -74,6 +75,7 @@ pkgCache::Header::Header() VersionCount = 0; DescriptionCount = 0; DependsCount = 0; + ReleaseFileCount = 0; PackageFileCount = 0; VerFileCount = 0; DescFileCount = 0; @@ -82,6 +84,7 @@ pkgCache::Header::Header() MaxDescFileSize = 0; FileList = 0; + RlsFileList = 0; #if APT_PKG_ABI < 413 APT_IGNORE_DEPRECATED(StringList = 0;) #endif @@ -102,6 +105,7 @@ bool pkgCache::Header::CheckSizes(Header &Against) const if (HeaderSz == Against.HeaderSz && GroupSz == Against.GroupSz && PackageSz == Against.PackageSz && + ReleaseFileSz == Against.ReleaseFileSz && PackageFileSz == Against.PackageFileSz && VersionSz == Against.VersionSz && DescriptionSz == Against.DescriptionSz && @@ -140,6 +144,7 @@ bool pkgCache::ReMap(bool const &Errorchecks) PkgP = (Package *)Map.Data(); VerFileP = (VerFile *)Map.Data(); DescFileP = (DescFile *)Map.Data(); + RlsFileP = (ReleaseFile *)Map.Data(); PkgFileP = (PackageFile *)Map.Data(); VerP = (Version *)Map.Data(); DescP = (Description *)Map.Data(); @@ -814,7 +819,7 @@ APT_PURE bool pkgCache::VerIterator::Downloadable() const { VerFileIterator Files = FileList(); for (; Files.end() == false; ++Files) - if ((Files.File()->Flags & pkgCache::Flag::NotSource) != pkgCache::Flag::NotSource) + if (Files.File().Flagged(pkgCache::Flag::NotSource) == false) return true; return false; } @@ -828,7 +833,7 @@ APT_PURE bool pkgCache::VerIterator::Automatic() const VerFileIterator Files = FileList(); for (; Files.end() == false; ++Files) // Do not check ButAutomaticUpgrades here as it is kind of automatic… - if ((Files.File()->Flags & pkgCache::Flag::NotAutomatic) != pkgCache::Flag::NotAutomatic) + if (Files.File().Flagged(pkgCache::Flag::NotAutomatic) == false) return true; return false; } @@ -861,27 +866,27 @@ string pkgCache::VerIterator::RelStr() const for (pkgCache::VerFileIterator I = this->FileList(); I.end() == false; ++I) { // Do not print 'not source' entries' - pkgCache::PkgFileIterator File = I.File(); - if ((File->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource) + pkgCache::PkgFileIterator const File = I.File(); + if (File.Flagged(pkgCache::Flag::NotSource)) continue; // See if we have already printed this out.. bool Seen = false; for (pkgCache::VerFileIterator J = this->FileList(); I != J; ++J) { - pkgCache::PkgFileIterator File2 = J.File(); - if (File2->Label == 0 || File->Label == 0) + pkgCache::PkgFileIterator const File2 = J.File(); + if (File2.Label() == 0 || File.Label() == 0) continue; if (strcmp(File.Label(),File2.Label()) != 0) continue; - if (File2->Version == File->Version) + if (File2.Version() == File.Version()) { Seen = true; break; } - if (File2->Version == 0 || File->Version == 0) + if (File2.Version() == 0 || File.Version() == 0) break; if (strcmp(File.Version(),File2.Version()) == 0) Seen = true; @@ -895,12 +900,12 @@ string pkgCache::VerIterator::RelStr() const else First = false; - if (File->Label != 0) + if (File.Label() != 0) Res = Res + File.Label() + ':'; - if (File->Archive != 0) + if (File.Archive() != 0) { - if (File->Version == 0) + if (File.Version() == 0) Res += File.Archive(); else Res = Res + File.Version() + '/' + File.Archive(); @@ -908,7 +913,7 @@ string pkgCache::VerIterator::RelStr() const else { // No release file, print the host name that this came from - if (File->Site == 0 || File.Site()[0] == 0) + if (File.Site() == 0 || File.Site()[0] == 0) Res += "localhost"; else Res += File.Site(); @@ -931,12 +936,12 @@ const char * pkgCache::VerIterator::MultiArchType() const return "none"; } /*}}}*/ -// PkgFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/ +// RlsFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/ // --------------------------------------------------------------------- /* This stats the file and compares its stats with the ones that were - stored during generation. Date checks should probably also be + stored during generation. Date checks should probably also be included here. */ -bool pkgCache::PkgFileIterator::IsOk() +bool pkgCache::RlsFileIterator::IsOk() { struct stat Buf; if (stat(FileName(),&Buf) != 0) @@ -948,10 +953,8 @@ bool pkgCache::PkgFileIterator::IsOk() return true; } /*}}}*/ -// PkgFileIterator::RelStr - Return the release string /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string pkgCache::PkgFileIterator::RelStr() +// RlsFileIterator::RelStr - Return the release string /*{{{*/ +string pkgCache::RlsFileIterator::RelStr() { string Res; if (Version() != 0) @@ -964,8 +967,40 @@ string pkgCache::PkgFileIterator::RelStr() Res = Res + (Res.empty() == true?"n=":",n=") + Codename(); if (Label() != 0) Res = Res + (Res.empty() == true?"l=":",l=") + Label(); - if (Component() != 0) - Res = Res + (Res.empty() == true?"c=":",c=") + Component(); + return Res; +} + /*}}}*/ +// PkgFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/ +// --------------------------------------------------------------------- +/* This stats the file and compares its stats with the ones that were + stored during generation. Date checks should probably also be + included here. */ +bool pkgCache::PkgFileIterator::IsOk() +{ + struct stat Buf; + if (stat(FileName(),&Buf) != 0) + return false; + + if (Buf.st_size != (signed)S->Size || Buf.st_mtime != S->mtime) + return false; + + return true; +} + /*}}}*/ +string pkgCache::PkgFileIterator::RelStr() /*{{{*/ +{ + std::string Res; + if (ReleaseFile() == 0) + { + if (Component() != 0) + Res = Res + (Res.empty() == true?"a=":",a=") + Component(); + } + else + { + Res = ReleaseFile().RelStr(); + if (Component() != 0) + Res = Res + (Res.empty() == true?"c=":",c=") + Component(); + } if (Architecture() != 0) Res = Res + (Res.empty() == true?"b=":",b=") + Architecture(); return Res; diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index b4d56611a..696b3b94d 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -133,6 +133,7 @@ class pkgCache /*{{{*/ struct Header; struct Group; struct Package; + struct ReleaseFile; struct PackageFile; struct Version; struct Description; @@ -150,6 +151,7 @@ class pkgCache /*{{{*/ class DescIterator; class DepIterator; class PrvIterator; + class RlsFileIterator; class PkgFileIterator; class VerFileIterator; class DescFileIterator; @@ -192,9 +194,11 @@ class pkgCache /*{{{*/ enum PkgFlags {Auto=(1<<0),Essential=(1<<3),Important=(1<<4)}; enum PkgFFlags { NotSource=(1<<0), /*!< packages can't be fetched from here, e.g. dpkg/status file */ - NotAutomatic=(1<<1), /*!< archive has a default pin of 1 */ - ButAutomaticUpgrades=(1<<2), /*!< (together with the previous) archive has a default pin of 100 */ - LocalSource=(1<<3), /*!< local sources can't and will not be verified by hashes */ + LocalSource=(1<<1), /*!< local sources can't and will not be verified by hashes */ + }; + enum ReleaseFileFlags { + NotAutomatic=(1<<0), /*!< archive has a default pin of 1 */ + ButAutomaticUpgrades=(1<<1), /*!< (together with the previous) archive has a default pin of 100 */ }; }; @@ -215,6 +219,7 @@ class pkgCache /*{{{*/ Package *PkgP; VerFile *VerFileP; DescFile *DescFileP; + ReleaseFile *RlsFileP; PackageFile *PkgFileP; Version *VerP; Description *DescP; @@ -247,6 +252,8 @@ class pkgCache /*{{{*/ inline PkgIterator PkgEnd(); inline PkgFileIterator FileBegin(); inline PkgFileIterator FileEnd(); + inline RlsFileIterator RlsFileBegin(); + inline RlsFileIterator RlsFileEnd(); inline bool MultiArchCache() const { return MultiArchEnabled; } inline char const * NativeArch(); @@ -296,6 +303,7 @@ struct pkgCache::Header unsigned short HeaderSz; unsigned short GroupSz; unsigned short PackageSz; + unsigned short ReleaseFileSz; unsigned short PackageFileSz; unsigned short VersionSz; unsigned short DescriptionSz; @@ -314,6 +322,7 @@ struct pkgCache::Header map_id_t VersionCount; map_id_t DescriptionCount; map_id_t DependsCount; + map_fileid_t ReleaseFileCount; map_fileid_t PackageFileCount; map_fileid_t VerFileCount; map_fileid_t DescFileCount; @@ -324,6 +333,9 @@ struct pkgCache::Header The PackageFile structures are singly linked lists that represent all package files that have been merged into the cache. */ map_pointer_t FileList; + /** \brief index of the first ReleaseFile structure */ + map_pointer_t RlsFileList; + #if APT_PKG_ABI < 413 APT_DEPRECATED map_pointer_t StringList; #endif @@ -482,15 +494,14 @@ struct pkgCache::Package unsigned long Flags; }; /*}}}*/ -// Package File structure /*{{{*/ -/** \brief stores information about the files used to generate the cache +// Release File structure /*{{{*/ +/** \brief stores information about the release files used to generate the cache - Package files are referenced by Version structures to be able to know - after the generation still from which Packages file includes this Version - as we need this information later on e.g. for pinning. */ -struct pkgCache::PackageFile + PackageFiles reference ReleaseFiles as we need to keep record of which + version belongs to which release e.g. for pinning. */ +struct pkgCache::ReleaseFile { - /** \brief physical disk file that this PackageFile represents */ + /** \brief physical disk file that this ReleaseFile represents */ map_stringitem_t FileName; /** \brief the release information @@ -498,13 +509,47 @@ struct pkgCache::PackageFile release information means. */ map_stringitem_t Archive; map_stringitem_t Codename; - map_stringitem_t Component; map_stringitem_t Version; map_stringitem_t Origin; map_stringitem_t Label; - map_stringitem_t Architecture; /** \brief The site the index file was fetched from */ map_stringitem_t Site; + + /** \brief Size of the file + + Used together with the modification time as a + simple check to ensure that the Packages + file has not been altered since Cache generation. */ + map_filesize_t Size; + /** \brief Modification time for the file */ + time_t mtime; + + /** @TODO document PackageFile::Flags */ + unsigned long Flags; + + // Linked list + /** \brief Link to the next ReleaseFile in the Cache */ + map_pointer_t NextFile; + /** \brief unique sequel ID */ + should_be_map_fileid_t ID; +}; + /*}}}*/ +// Package File structure /*{{{*/ +/** \brief stores information about the files used to generate the cache + + Package files are referenced by Version structures to be able to know + after the generation still from which Packages file includes this Version + as we need this information later on e.g. for pinning. */ +struct pkgCache::PackageFile +{ + /** \brief physical disk file that this PackageFile represents */ + map_stringitem_t FileName; + /** \brief the release information */ + map_pointer_t Release; + + map_stringitem_t Component; + map_stringitem_t Architecture; + /** \brief indicates what sort of index file this is @TODO enumerate at least the possible indexes */ @@ -744,6 +789,11 @@ inline pkgCache::PkgFileIterator pkgCache::FileBegin() {return PkgFileIterator(*this,PkgFileP + HeaderP->FileList);} inline pkgCache::PkgFileIterator pkgCache::FileEnd() {return PkgFileIterator(*this,PkgFileP);} +inline pkgCache::RlsFileIterator pkgCache::RlsFileBegin() + {return RlsFileIterator(*this,RlsFileP + HeaderP->RlsFileList);} +inline pkgCache::RlsFileIterator pkgCache::RlsFileEnd() + {return RlsFileIterator(*this,RlsFileP);} + // Oh I wish for Real Name Space Support class pkgCache::Namespace /*{{{*/ @@ -755,6 +805,7 @@ class pkgCache::Namespace /*{{{*/ typedef pkgCache::DescIterator DescIterator; typedef pkgCache::DepIterator DepIterator; typedef pkgCache::PrvIterator PrvIterator; + typedef pkgCache::RlsFileIterator RlsFileIterator; typedef pkgCache::PkgFileIterator PkgFileIterator; typedef pkgCache::VerFileIterator VerFileIterator; typedef pkgCache::Version Version; diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index ba454f057..2d0e3960d 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -54,10 +54,8 @@ using std::string; /* We set the dirty flag and make sure that is written to the disk */ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) : Map(*pMap), Cache(pMap,false), Progress(Prog), - FoundFileDeps(0) + CurrentRlsFile(NULL), CurrentFile(NULL), FoundFileDeps(0) { - CurrentFile = 0; - if (_error->PendingError() == true) return; @@ -145,6 +143,7 @@ void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newM Cache.ReMap(false); CurrentFile += (pkgCache::PackageFile const * const) newMap - (pkgCache::PackageFile const * const) oldMap; + CurrentRlsFile += (pkgCache::ReleaseFile const * const) newMap - (pkgCache::ReleaseFile const * const) oldMap; for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) @@ -167,6 +166,9 @@ void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newM for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) (*i)->ReMap(oldMap, newMap); + for (std::vector::const_iterator i = Dynamic::toReMap.begin(); + i != Dynamic::toReMap.end(); ++i) + (*i)->ReMap(oldMap, newMap); } /*}}}*/ // CacheGenerator::WriteStringInMap /*{{{*/ map_stringitem_t pkgCacheGenerator::WriteStringInMap(const char *String, @@ -1072,13 +1074,47 @@ bool pkgCacheGenerator::ListParser::SameVersion(unsigned short const Hash,/*{{{* return Hash == Ver->Hash; } /*}}}*/ +// CacheGenerator::SelectReleaseFile - Select the current release file the indexes belong to /*{{{*/ +bool pkgCacheGenerator::SelectReleaseFile(const string &File,const string &Site, + unsigned long Flags) +{ + if (File.empty() && Site.empty()) + { + CurrentRlsFile = NULL; + return true; + } + + // Get some space for the structure + map_pointer_t const idxFile = AllocateInMap(sizeof(*CurrentRlsFile)); + if (unlikely(idxFile == 0)) + return false; + CurrentRlsFile = Cache.RlsFileP + idxFile; + + // Fill it in + map_stringitem_t const idxFileName = WriteStringInMap(File); + map_stringitem_t const idxSite = StoreString(MIXED, Site); + if (unlikely(idxFileName == 0 || idxSite == 0)) + return false; + CurrentRlsFile->FileName = idxFileName; + CurrentRlsFile->Site = idxSite; + CurrentRlsFile->NextFile = Cache.HeaderP->RlsFileList; + CurrentRlsFile->Flags = Flags; + CurrentRlsFile->ID = Cache.HeaderP->ReleaseFileCount; + RlsFileName = File; + Cache.HeaderP->RlsFileList = CurrentRlsFile - Cache.RlsFileP; + Cache.HeaderP->ReleaseFileCount++; + + return true; +} + /*}}}*/ // CacheGenerator::SelectFile - Select the current file being parsed /*{{{*/ // --------------------------------------------------------------------- /* This is used to select which file is to be associated with all newly added versions. The caller is responsible for setting the IMS fields. */ -bool pkgCacheGenerator::SelectFile(const string &File,const string &Site, - const pkgIndexFile &Index, - unsigned long Flags) +bool pkgCacheGenerator::SelectFile(std::string const &File, + pkgIndexFile const &Index, + std::string const &Component, + unsigned long const Flags) { // Get some space for the structure map_pointer_t const idxFile = AllocateInMap(sizeof(*CurrentFile)); @@ -1088,18 +1124,24 @@ bool pkgCacheGenerator::SelectFile(const string &File,const string &Site, // Fill it in map_stringitem_t const idxFileName = WriteStringInMap(File); - map_stringitem_t const idxSite = StoreString(MIXED, Site); - if (unlikely(idxFileName == 0 || idxSite == 0)) + if (unlikely(idxFileName == 0)) return false; CurrentFile->FileName = idxFileName; - CurrentFile->Site = idxSite; CurrentFile->NextFile = Cache.HeaderP->FileList; - CurrentFile->Flags = Flags; CurrentFile->ID = Cache.HeaderP->PackageFileCount; map_stringitem_t const idxIndexType = StoreString(MIXED, Index.GetType()->Label); if (unlikely(idxIndexType == 0)) return false; CurrentFile->IndexType = idxIndexType; + map_stringitem_t const component = StoreString(pkgCacheGenerator::MIXED, Component); + if (unlikely(component == 0)) + return false; + CurrentFile->Component = component; + CurrentFile->Flags = Flags; + if (CurrentRlsFile != NULL) + CurrentFile->Release = CurrentRlsFile - Cache.RlsFileP; + else + CurrentFile->Release = 0; PkgFileName = File; Cache.HeaderP->FileList = CurrentFile - Cache.PkgFileP; Cache.HeaderP->PackageFileCount++; @@ -1174,35 +1216,59 @@ static bool CheckValidity(const string &CacheFile, _error->Discard(); return false; } - + + SPtrArray RlsVisited = new bool[Cache.HeaderP->ReleaseFileCount]; + memset(RlsVisited,0,sizeof(*RlsVisited)*Cache.HeaderP->ReleaseFileCount); + std::vector Files; + for (pkgSourceList::const_iterator i = List.begin(); i != List.end(); ++i) + { + if (Debug == true) + std::clog << "Checking RlsFile " << (*i)->Describe() << ": "; + pkgCache::RlsFileIterator const RlsFile = (*i)->FindInCache(Cache); + if (RlsFile.end() == true) + { + if (Debug == true) + std::clog << "FindInCache returned end-Pointer" << std::endl; + return false; + } + + RlsVisited[RlsFile->ID] = true; + if (Debug == true) + std::clog << "with ID " << RlsFile->ID << " is valid" << std::endl; + + std::vector *Indexes = (*i)->GetIndexFiles(); + for (std::vector::const_iterator j = Indexes->begin(); j != Indexes->end(); ++j) + if ((*j)->HasPackages()) + Files.push_back (*j); + } + for (unsigned I = 0; I != Cache.HeaderP->ReleaseFileCount; ++I) + if (RlsVisited[I] == false) + { + if (Debug == true) + std::clog << "RlsFile with ID" << I << " wasn't visited" << std::endl; + return false; + } + + for (; Start != End; ++Start) + Files.push_back(*Start); + /* Now we check every index file, see if it is in the cache, verify the IMS data and check that it is on the disk too.. */ SPtrArray Visited = new bool[Cache.HeaderP->PackageFileCount]; memset(Visited,0,sizeof(*Visited)*Cache.HeaderP->PackageFileCount); - for (; Start != End; ++Start) + for (std::vector::const_reverse_iterator PkgFile = Files.rbegin(); PkgFile != Files.rend(); ++PkgFile) { if (Debug == true) - std::clog << "Checking PkgFile " << (*Start)->Describe() << ": "; - if ((*Start)->HasPackages() == false) - { - if (Debug == true) - std::clog << "Has NO packages" << std::endl; - continue; - } - - if ((*Start)->Exists() == false) + std::clog << "Checking PkgFile " << (*PkgFile)->Describe() << ": "; + if ((*PkgFile)->Exists() == false) { -#if 0 // mvo: we no longer give a message here (Default Sources spec) - _error->WarningE("stat",_("Couldn't stat source package list %s"), - (*Start)->Describe().c_str()); -#endif if (Debug == true) std::clog << "file doesn't exist" << std::endl; continue; } // FindInCache is also expected to do an IMS check. - pkgCache::PkgFileIterator File = (*Start)->FindInCache(Cache); + pkgCache::PkgFileIterator File = (*PkgFile)->FindInCache(Cache); if (File.end() == true) { if (Debug == true) @@ -1214,15 +1280,15 @@ static bool CheckValidity(const string &CacheFile, if (Debug == true) std::clog << "with ID " << File->ID << " is valid" << std::endl; } - + for (unsigned I = 0; I != Cache.HeaderP->PackageFileCount; I++) if (Visited[I] == false) { if (Debug == true) - std::clog << "File with ID" << I << " wasn't visited" << std::endl; + std::clog << "PkgFile with ID" << I << " wasn't visited" << std::endl; return false; } - + if (_error->PendingError() == true) { if (Debug == true) @@ -1243,9 +1309,20 @@ static bool CheckValidity(const string &CacheFile, // --------------------------------------------------------------------- /* Size is kind of an abstract notion that is only used for the progress meter */ -static map_filesize_t ComputeSize(FileIterator Start,FileIterator End) +static map_filesize_t ComputeSize(pkgSourceList const * const List, FileIterator Start,FileIterator End) { map_filesize_t TotalSize = 0; + if (List != NULL) + { + for (pkgSourceList::const_iterator i = List->begin(); i != List->end(); ++i) + { + std::vector *Indexes = (*i)->GetIndexFiles(); + for (std::vector::const_iterator j = Indexes->begin(); j != Indexes->end(); ++j) + if ((*j)->HasPackages() == true) + TotalSize += (*j)->Size(); + } + } + for (; Start < End; ++Start) { if ((*Start)->HasPackages() == false) @@ -1261,11 +1338,63 @@ static map_filesize_t ComputeSize(FileIterator Start,FileIterator End) static bool BuildCache(pkgCacheGenerator &Gen, OpProgress *Progress, map_filesize_t &CurrentSize,map_filesize_t TotalSize, + pkgSourceList const * const List, FileIterator Start, FileIterator End) { + std::vector Files; + bool const HasFileDeps = Gen.HasFileDeps(); + + if (List != NULL) + { + for (pkgSourceList::const_iterator i = List->begin(); i != List->end(); ++i) + { + if ((*i)->FindInCache(Gen.GetCache()).end() == false) + { + _error->Warning("Duplicate sources.list entry %s", + (*i)->Describe().c_str()); + continue; + } + + if ((*i)->Merge(Gen, Progress) == false) + return false; + + std::vector *Indexes = (*i)->GetIndexFiles(); + for (std::vector::const_iterator I = Indexes->begin(); I != Indexes->end(); ++I) + { + if (HasFileDeps) + Files.push_back(*I); + + if ((*I)->HasPackages() == false) + continue; + + if ((*I)->Exists() == false) + continue; + + if ((*I)->FindInCache(Gen.GetCache()).end() == false) + { + _error->Warning("Duplicate sources.list entry %s", + (*I)->Describe().c_str()); + continue; + } + + map_filesize_t Size = (*I)->Size(); + if (Progress != NULL) + Progress->OverallProgress(CurrentSize,TotalSize,Size,_("Reading package lists")); + CurrentSize += Size; + + if ((*I)->Merge(Gen,Progress) == false) + return false; + } + } + } + + Gen.SelectReleaseFile("", ""); FileIterator I; for (I = Start; I != End; ++I) { + if (HasFileDeps) + Files.push_back(*I); + if ((*I)->HasPackages() == false) continue; @@ -1288,13 +1417,13 @@ static bool BuildCache(pkgCacheGenerator &Gen, return false; } - if (Gen.HasFileDeps() == true) + if (HasFileDeps == true) { if (Progress != NULL) Progress->Done(); - TotalSize = ComputeSize(Start, End); + TotalSize = ComputeSize(List, Start, End); CurrentSize = 0; - for (I = Start; I != End; ++I) + for (std::vector::const_iterator I = Files.begin(); I != Files.end(); ++I) { map_filesize_t Size = (*I)->Size(); if (Progress != NULL) @@ -1339,6 +1468,7 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress bool const Debug = _config->FindB("Debug::pkgCacheGen", false); std::vector Files; + /* for (std::vector::const_iterator i = List.begin(); i != List.end(); ++i) @@ -1349,8 +1479,7 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress ++j) Files.push_back (*j); } - - map_filesize_t const EndOfSource = Files.size(); +*/ if (_system->AddStatusFiles(Files) == false) return false; @@ -1442,8 +1571,8 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress // Lets try the source cache. map_filesize_t CurrentSize = 0; map_filesize_t TotalSize = 0; - if (CheckValidity(SrcCacheFile, List, Files.begin(), - Files.begin()+EndOfSource) == true) + if (CheckValidity(SrcCacheFile, List, Files.end(), + Files.end()) == true) { if (Debug == true) std::clog << "srcpkgcache.bin is valid - populate MMap with it." << std::endl; @@ -1455,28 +1584,28 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress SCacheF.Size()) == false) return false; - TotalSize = ComputeSize(Files.begin()+EndOfSource,Files.end()); + TotalSize = ComputeSize(NULL, Files.begin(), Files.end()); // Build the status cache pkgCacheGenerator Gen(Map.Get(),Progress); if (_error->PendingError() == true) return false; - if (BuildCache(Gen,Progress,CurrentSize,TotalSize, - Files.begin()+EndOfSource,Files.end()) == false) + if (BuildCache(Gen, Progress, CurrentSize, TotalSize, NULL, + Files.begin(),Files.end()) == false) return false; } else { if (Debug == true) std::clog << "srcpkgcache.bin is NOT valid - rebuild" << std::endl; - TotalSize = ComputeSize(Files.begin(),Files.end()); + TotalSize = ComputeSize(&List, Files.begin(),Files.end()); // Build the source cache pkgCacheGenerator Gen(Map.Get(),Progress); if (_error->PendingError() == true) return false; - if (BuildCache(Gen,Progress,CurrentSize,TotalSize, - Files.begin(),Files.begin()+EndOfSource) == false) + if (BuildCache(Gen, Progress, CurrentSize, TotalSize, &List, + Files.end(),Files.end()) == false) return false; // Write it back @@ -1503,8 +1632,8 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress } // Build the status cache - if (BuildCache(Gen,Progress,CurrentSize,TotalSize, - Files.begin()+EndOfSource,Files.end()) == false) + if (BuildCache(Gen, Progress, CurrentSize, TotalSize, NULL, + Files.begin(), Files.end()) == false) return false; } if (Debug == true) @@ -1536,7 +1665,6 @@ APT_DEPRECATED bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **Ou bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap) { std::vector Files; - map_filesize_t EndOfSource = Files.size(); if (_system->AddStatusFiles(Files) == false) return false; @@ -1544,7 +1672,7 @@ bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **O map_filesize_t CurrentSize = 0; map_filesize_t TotalSize = 0; - TotalSize = ComputeSize(Files.begin()+EndOfSource,Files.end()); + TotalSize = ComputeSize(NULL, Files.begin(), Files.end()); // Build the status cache if (Progress != NULL) @@ -1552,8 +1680,8 @@ bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **O pkgCacheGenerator Gen(Map.Get(),Progress); if (_error->PendingError() == true) return false; - if (BuildCache(Gen,Progress,CurrentSize,TotalSize, - Files.begin()+EndOfSource,Files.end()) == false) + if (BuildCache(Gen,Progress,CurrentSize,TotalSize, NULL, + Files.begin(), Files.end()) == false) return false; if (_error->PendingError() == true) diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index c4ace713d..2795d09d6 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -69,7 +69,9 @@ class APT_HIDDEN pkgCacheGenerator /*{{{*/ DynamicMMap ⤅ pkgCache Cache; OpProgress *Progress; - + + std::string RlsFileName; + pkgCache::ReleaseFile *CurrentRlsFile; std::string PkgFileName; pkgCache::PackageFile *CurrentFile; @@ -100,12 +102,14 @@ class APT_HIDDEN pkgCacheGenerator /*{{{*/ inline map_stringitem_t StoreString(enum StringType const type, const std::string &S) {return StoreString(type, S.c_str(),S.length());}; void DropProgress() {Progress = 0;}; - bool SelectFile(const std::string &File,const std::string &Site,pkgIndexFile const &Index, - unsigned long Flags = 0); + bool SelectFile(const std::string &File,pkgIndexFile const &Index, std::string const &Component, unsigned long Flags = 0); + bool SelectReleaseFile(const std::string &File, const std::string &Site, unsigned long Flags = 0); bool MergeList(ListParser &List,pkgCache::VerIterator *Ver = 0); inline pkgCache &GetCache() {return Cache;}; inline pkgCache::PkgFileIterator GetCurFile() {return pkgCache::PkgFileIterator(Cache,CurrentFile);}; + inline pkgCache::RlsFileIterator GetCurRlsFile() + {return pkgCache::RlsFileIterator(Cache,CurrentRlsFile);}; bool HasFileDeps() {return FoundFileDeps;}; bool MergeFileProvides(ListParser &List); diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index 00693ce54..bd40ad2d9 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -63,9 +63,9 @@ pkgPolicy::pkgPolicy(pkgCache *Owner) : Pins(0), PFPriority(0), Cache(Owner) pkgVersionMatch vm("", pkgVersionMatch::None); for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F) { - if ((F->Archive != 0 && vm.ExpressionMatches(DefRel, F.Archive()) == true) || - (F->Codename != 0 && vm.ExpressionMatches(DefRel, F.Codename()) == true) || - (F->Version != 0 && vm.ExpressionMatches(DefRel, F.Version()) == true) || + if (vm.ExpressionMatches(DefRel, F.Archive()) || + vm.ExpressionMatches(DefRel, F.Codename()) || + vm.ExpressionMatches(DefRel, F.Version()) || (DefRel.length() > 2 && DefRel[1] == '=')) found = true; } @@ -86,11 +86,11 @@ bool pkgPolicy::InitDefaults() for (pkgCache::PkgFileIterator I = Cache->FileBegin(); I != Cache->FileEnd(); ++I) { PFPriority[I->ID] = 500; - if ((I->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource) + if (I.Flagged(pkgCache::Flag::NotSource)) PFPriority[I->ID] = 100; - else if ((I->Flags & pkgCache::Flag::ButAutomaticUpgrades) == pkgCache::Flag::ButAutomaticUpgrades) + else if (I.Flagged(pkgCache::Flag::ButAutomaticUpgrades)) PFPriority[I->ID] = 100; - else if ((I->Flags & pkgCache::Flag::NotAutomatic) == pkgCache::Flag::NotAutomatic) + else if (I.Flagged(pkgCache::Flag::NotAutomatic)) PFPriority[I->ID] = 1; } @@ -170,8 +170,7 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pk then it is not a candidate for installation, ever. This weeds out bogus entries that may be due to config-file states, or other. */ - if ((VF.File()->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource && - instVer == false) + if (VF.File().Flagged(pkgCache::Flag::NotSource) && instVer == false) continue; signed Prio = PFPriority[VF.File()->ID]; diff --git a/apt-pkg/versionmatch.cc b/apt-pkg/versionmatch.cc index 284098bdf..86c1b7d4a 100644 --- a/apt-pkg/versionmatch.cc +++ b/apt-pkg/versionmatch.cc @@ -137,7 +137,10 @@ pkgVersionMatch::pkgVersionMatch(string Data,MatchType Type) : Type(Type) // --------------------------------------------------------------------- /* */ bool pkgVersionMatch::MatchVer(const char *A,string B,bool Prefix) -{ +{ + if (A == NULL) + return false; + const char *Ab = A; const char *Ae = Ab + strlen(A); @@ -178,13 +181,16 @@ pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg) // This will be Ended by now. return Ver; } + /*}}}*/ #ifndef FNM_CASEFOLD #define FNM_CASEFOLD 0 #endif -bool pkgVersionMatch::ExpressionMatches(const char *pattern, const char *string) +bool pkgVersionMatch::ExpressionMatches(const char *pattern, const char *string)/*{{{*/ { + if (pattern == NULL || string == NULL) + return false; if (pattern[0] == '/') { size_t length = strlen(pattern); if (pattern[length - 1] == '/') { @@ -230,38 +236,30 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File) return false; if (RelVerStr.empty() == false) - if (File->Version == 0 || - (MatchVer(File.Version(),RelVerStr,RelVerPrefixMatch) == false && - ExpressionMatches(RelVerStr, File.Version()) == false)) + if (MatchVer(File.Version(),RelVerStr,RelVerPrefixMatch) == false && + ExpressionMatches(RelVerStr, File.Version()) == false) return false; if (RelOrigin.empty() == false) - if (File->Origin == 0 || !ExpressionMatches(RelOrigin,File.Origin())) + if (!ExpressionMatches(RelOrigin,File.Origin())) return false; if (RelArchive.empty() == false) - if (File->Archive == 0 || - !ExpressionMatches(RelArchive,File.Archive())) + if (!ExpressionMatches(RelArchive,File.Archive())) return false; if (RelCodename.empty() == false) - if (File->Codename == 0 || - !ExpressionMatches(RelCodename,File.Codename())) + if (!ExpressionMatches(RelCodename,File.Codename())) return false; if (RelRelease.empty() == false) - if ((File->Archive == 0 || - !ExpressionMatches(RelRelease,File.Archive())) && - (File->Codename == 0 || - !ExpressionMatches(RelRelease,File.Codename()))) + if (!ExpressionMatches(RelRelease,File.Archive()) && + !ExpressionMatches(RelRelease,File.Codename())) return false; if (RelLabel.empty() == false) - if (File->Label == 0 || - !ExpressionMatches(RelLabel,File.Label())) + if (!ExpressionMatches(RelLabel,File.Label())) return false; if (RelComponent.empty() == false) - if (File->Component == 0 || - !ExpressionMatches(RelComponent,File.Component())) + if (!ExpressionMatches(RelComponent,File.Component())) return false; if (RelArchitecture.empty() == false) - if (File->Architecture == 0 || - !ExpressionMatches(RelArchitecture,File.Architecture())) + if (!ExpressionMatches(RelArchitecture,File.Architecture())) return false; return true; } @@ -269,11 +267,14 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File) if (Type == Origin) { if (OrSite.empty() == false) { - if (File->Site == 0) + if (File.Site() == NULL) return false; } else // so we are talking about file:// or status file - if (strcmp(File.Site(),"") == 0 && File->Archive != 0 && strcmp(File.Archive(),"now") == 0) // skip the status file + { + pkgCache::RlsFileIterator const RlsFile = File.ReleaseFile(); + if (strcmp(File.Site(),"") == 0 && RlsFile->Archive != 0 && strcmp(RlsFile.Archive(),"now") == 0) // skip the status file return false; + } return (ExpressionMatches(OrSite, File.Site())); /* both strings match */ } diff --git a/apt-pkg/versionmatch.h b/apt-pkg/versionmatch.h index 4c8f704c8..bb950b9c7 100644 --- a/apt-pkg/versionmatch.h +++ b/apt-pkg/versionmatch.h @@ -70,8 +70,8 @@ class pkgVersionMatch enum MatchType {None = 0,Version,Release,Origin} Type; bool MatchVer(const char *A,std::string B,bool Prefix) APT_PURE; - bool ExpressionMatches(const char *pattern, const char *string); - bool ExpressionMatches(const std::string& pattern, const char *string); + static bool ExpressionMatches(const char *pattern, const char *string); + static bool ExpressionMatches(const std::string& pattern, const char *string); bool FileMatch(pkgCache::PkgFileIterator File); pkgCache::VerIterator Find(pkgCache::PkgIterator Pkg); diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 690b03bcc..3b8ebc96d 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -413,17 +413,21 @@ static bool Stats(CommandLine &) stritems.insert(Prv->ProvideVersion); } } - for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F) + for (pkgCache::RlsFileIterator F = Cache->RlsFileBegin(); F != Cache->RlsFileEnd(); ++F) { stritems.insert(F->FileName); stritems.insert(F->Archive); stritems.insert(F->Codename); - stritems.insert(F->Component); stritems.insert(F->Version); stritems.insert(F->Origin); stritems.insert(F->Label); - stritems.insert(F->Architecture); stritems.insert(F->Site); + } + for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F) + { + stritems.insert(F->FileName); + stritems.insert(F->Architecture); + stritems.insert(F->Component); stritems.insert(F->IndexType); } unsigned long Size = 0; @@ -446,6 +450,7 @@ static bool Stats(CommandLine &) APT_CACHESIZE(VersionCount, VersionSz) + APT_CACHESIZE(DescriptionCount, DescriptionSz) + APT_CACHESIZE(DependsCount, DependencySz) + + APT_CACHESIZE(ReleaseFileCount, ReleaseFileSz) + APT_CACHESIZE(PackageFileCount, PackageFileSz) + APT_CACHESIZE(VerFileCount, VerFileSz) + APT_CACHESIZE(DescFileCount, DescFileSz) + diff --git a/test/integration/framework b/test/integration/framework index 110758e82..7b03c09ef 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -137,7 +137,14 @@ dpkgcheckbuilddeps() { command dpkg-checkbuilddeps --admindir=${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg "$@" } gdb() { - local CMD="$1" + local CMD + case "$1" in + aptget) CMD="apt-get";; + aptcache) CMD="apt-cache";; + aptmark) CMD="apt-mark";; + apthelper) CMD="apt-helper";; + *) CMD="$1";; + esac shift runapt command gdb --quiet -ex run "${BUILDDIRECTORY}/$CMD" --args "${BUILDDIRECTORY}/$CMD" "$@" } diff --git a/test/integration/test-policy-pinning b/test/integration/test-policy-pinning index 9cd54264b..9f7f457ae 100755 --- a/test/integration/test-policy-pinning +++ b/test/integration/test-policy-pinning @@ -22,7 +22,7 @@ testequalpolicy() { release a=now $(echo "$AP" | awk '{ printf("%3s\n",$0) }') file:${APTARCHIVE} Packages release c= -Pinned packages:" aptcache policy $* +Pinned packages:" aptcache policy "$@" } testglobalpolicy() { -- cgit v1.2.3-70-g09d2 From d56e2917f27a722b54685de13aeb1bb7592fc61b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 13 Jun 2015 11:13:45 +0200 Subject: provide a public interface for acquiring changelogs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provided is a specialized acquire item which given a version can figure out the correct URI to try by itself and if not provides an error message alongside with static methods to get just the URI it would try to download if it should just be displayed or similar such. The URI is constructed as follows: Release files can provide an URI template in the "Changelogs" field, otherwise we lookup a configuration item based on the "Label" or "Origin" of the Release file to get a (hopefully known) default value for now. This template should contain the string CHANGEPATH which is replaced with the information about the version we want the changelog for (e.g. main/a/apt/apt_1.1). This middleway was choosen as this path part was consistent over the three known implementations (+1 defunct), while the rest of the URI varies widely between them. The benefit of this construct is that it is now easy to get changelogs for Debian packages on Ubuntu and vice versa – even at the moment where the Changelogs field is present nowhere. Strictly better than what apt-get had before as it would even fail to get changelogs from security… Now it will notice that security identifies as Origin: Debian and pick this setting (assuming again that no Changelogs field exists). If on the other hand security would ship its changelogs in a different location we could set it via the Label option overruling Origin. Closes: 687147, 739854, 784027, 787190 --- apt-pkg/acquire-item.cc | 211 +++++++++++++++++++++ apt-pkg/acquire-item.h | 114 +++++++++++ apt-pkg/init.cc | 4 + cmdline/apt-get.cc | 204 ++++---------------- doc/apt-get.8.xml | 16 +- doc/apt.conf.5.xml | 27 +++ doc/examples/configure-index | 11 +- test/integration/framework | 24 ++- test/integration/test-apt-get-changelog | 104 +++++++--- .../test-bug-722207-print-uris-even-if-very-quiet | 3 +- test/integration/test-bug-738785-switch-protocol | 7 +- vendor/ubuntu/apt.conf-01-vendor-ubuntu | 6 - 12 files changed, 507 insertions(+), 224 deletions(-) (limited to 'test/integration/framework') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index d6e9ccbe0..4bf4e62f8 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -2836,6 +2837,216 @@ std::string pkgAcqArchive::ShortDesc() const /*{{{*/ } /*}}}*/ +// AcqChangelog::pkgAcqChangelog - Constructors /*{{{*/ +pkgAcqChangelog::pkgAcqChangelog(pkgAcquire * const Owner, pkgCache::VerIterator const &Ver, + std::string const &DestDir, std::string const &DestFilename) : + pkgAcquire::Item(Owner), d(NULL), SrcName(Ver.SourcePkgName()), SrcVersion(Ver.SourceVerStr()) +{ + Desc.URI = URI(Ver); + Init(DestDir, DestFilename); +} +// some parameters are char* here as they come likely from char* interfaces – which can also return NULL +pkgAcqChangelog::pkgAcqChangelog(pkgAcquire * const Owner, pkgCache::RlsFileIterator const &RlsFile, + char const * const Component, char const * const SrcName, char const * const SrcVersion, + const string &DestDir, const string &DestFilename) : + pkgAcquire::Item(Owner), d(NULL), SrcName(SrcName), SrcVersion(SrcVersion) +{ + Desc.URI = URI(RlsFile, Component, SrcName, SrcVersion); + Init(DestDir, DestFilename); +} +pkgAcqChangelog::pkgAcqChangelog(pkgAcquire * const Owner, + std::string const &URI, char const * const SrcName, char const * const SrcVersion, + const string &DestDir, const string &DestFilename) : + pkgAcquire::Item(Owner), d(NULL), SrcName(SrcName), SrcVersion(SrcVersion) +{ + Desc.URI = URI; + Init(DestDir, DestFilename); +} +void pkgAcqChangelog::Init(std::string const &DestDir, std::string const &DestFilename) +{ + if (Desc.URI.empty()) + { + Status = StatError; + // TRANSLATOR: %s=%s is sourcename=sourceversion, e.g. apt=1.1 + strprintf(ErrorText, _("Changelog unavailable for %s=%s"), SrcName.c_str(), SrcVersion.c_str()); + // Let the error message print something sensible rather than "Failed to fetch /" + if (DestFilename.empty()) + DestFile = SrcName + ".changelog"; + else + DestFile = DestFilename; + Desc.URI = "changelog:/" + DestFile; + return; + } + + if (DestDir.empty()) + { + std::string const systemTemp = GetTempDir(); + char tmpname[100]; + snprintf(tmpname, sizeof(tmpname), "%s/apt-changelog-XXXXXX", systemTemp.c_str()); + if (NULL == mkdtemp(tmpname)) + { + _error->Errno("mkdtemp", "mkdtemp failed in changelog acquire of %s %s", SrcName.c_str(), SrcVersion.c_str()); + Status = StatError; + return; + } + DestFile = TemporaryDirectory = tmpname; + } + else + DestFile = DestDir; + + if (DestFilename.empty()) + DestFile = flCombine(DestFile, SrcName + ".changelog"); + else + DestFile = flCombine(DestFile, DestFilename); + + Desc.ShortDesc = "Changelog"; + strprintf(Desc.Description, "%s %s %s Changelog", URI::SiteOnly(Desc.URI).c_str(), SrcName.c_str(), SrcVersion.c_str()); + Desc.Owner = this; + QueueURI(Desc); + + if (Status == StatDone) // this happens if we queue the same changelog two times + { + Complete = true; + for (pkgAcquire::UriIterator I = Owner->UriBegin(); I != Owner->UriEnd(); ++I) + if (I->URI == Desc.URI) + if (DestFile != I->Owner->DestFile) + if (symlink(I->Owner->DestFile.c_str(), DestFile.c_str()) != 0) + { + ; // ignore error, there isn't anthing we could do to handle the edgecase of an edgecase + } + } +} + /*}}}*/ +std::string pkgAcqChangelog::URI(pkgCache::VerIterator const &Ver) /*{{{*/ +{ + char const * const SrcName = Ver.SourcePkgName(); + char const * const SrcVersion = Ver.SourceVerStr(); + pkgCache::PkgFileIterator PkgFile; + // find the first source for this version which promises a changelog + for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false; ++VF) + { + pkgCache::PkgFileIterator const PF = VF.File(); + if (PF.Flagged(pkgCache::Flag::NotSource) || PF->Release == 0) + continue; + PkgFile = PF; + pkgCache::RlsFileIterator const RF = PF.ReleaseFile(); + std::string const uri = URI(RF, PF.Component(), SrcName, SrcVersion); + if (uri.empty()) + continue; + return uri; + } + return ""; +} +std::string pkgAcqChangelog::URITemplate(pkgCache::RlsFileIterator const &Rls) +{ + if (Rls.end() == true || (Rls->Label == 0 && Rls->Origin == 0)) + return ""; + std::string const serverConfig = "Acquire::Changelogs::URI"; + std::string server; +#define APT_EMPTY_SERVER \ + if (server.empty() == false) \ + { \ + if (server != "no") \ + return server; \ + return ""; \ + } +#define APT_CHECK_SERVER(X, Y) \ + if (Rls->X != 0) \ + { \ + std::string const specialServerConfig = serverConfig + "::" + Y + #X + "::" + Rls.X(); \ + server = _config->Find(specialServerConfig); \ + APT_EMPTY_SERVER \ + } + // this way e.g. Debian-Security can fallback to Debian + APT_CHECK_SERVER(Label, "Override::") + APT_CHECK_SERVER(Origin, "Override::") + + if (RealFileExists(Rls.FileName())) + { + _error->PushToStack(); + FileFd rf; + /* This can be costly. A caller wanting to get millions of URIs might + want to do this on its own once and use Override settings. + We don't do this here as Origin/Label are not as unique as they + should be so this could produce request order-dependent anomalies */ + if (OpenMaybeClearSignedFile(Rls.FileName(), rf) == true) + { + pkgTagFile TagFile(&rf, rf.Size()); + pkgTagSection Section; + if (TagFile.Step(Section) == true) + server = Section.FindS("Changelogs"); + } + _error->RevertToStack(); + APT_EMPTY_SERVER + } + + APT_CHECK_SERVER(Label, "") + APT_CHECK_SERVER(Origin, "") +#undef APT_CHECK_SERVER +#undef APT_EMPTY_SERVER + return ""; +} +std::string pkgAcqChangelog::URI(pkgCache::RlsFileIterator const &Rls, + char const * const Component, char const * const SrcName, + char const * const SrcVersion) +{ + return URI(URITemplate(Rls), Component, SrcName, SrcVersion); +} +std::string pkgAcqChangelog::URI(std::string const &Template, + char const * const Component, char const * const SrcName, + char const * const SrcVersion) +{ + if (Template.find("CHANGEPATH") == std::string::npos) + return ""; + + // the path is: COMPONENT/SRC/SRCNAME/SRCNAME_SRCVER, e.g. main/a/apt/1.1 or contrib/liba/libapt/2.0 + std::string Src = SrcName; + std::string path = APT::String::Startswith(SrcName, "lib") ? Src.substr(0, 4) : Src.substr(0,1); + path.append("/").append(Src).append("/"); + path.append(Src).append("_").append(StripEpoch(SrcVersion)); + // we omit component for releases without one (= flat-style repositories) + if (Component != NULL && strlen(Component) != 0) + path = std::string(Component) + "/" + path; + + return SubstVar(Template, "CHANGEPATH", path); +} + /*}}}*/ +// AcqChangelog::Failed - Failure handler /*{{{*/ +void pkgAcqChangelog::Failed(string const &Message, pkgAcquire::MethodConfig const * const Cnf) +{ + Item::Failed(Message,Cnf); + + std::string errText; + // TRANSLATOR: %s=%s is sourcename=sourceversion, e.g. apt=1.1 + strprintf(errText, _("Changelog unavailable for %s=%s"), SrcName.c_str(), SrcVersion.c_str()); + + // Error is probably something techy like 404 Not Found + if (ErrorText.empty()) + ErrorText = errText; + else + ErrorText = errText + " (" + ErrorText + ")"; + return; +} + /*}}}*/ +// AcqChangelog::Done - Item downloaded OK /*{{{*/ +void pkgAcqChangelog::Done(string const &Message,HashStringList const &CalcHashes, + pkgAcquire::MethodConfig const * const Cnf) +{ + Item::Done(Message,CalcHashes,Cnf); + + Complete = true; +} + /*}}}*/ +pkgAcqChangelog::~pkgAcqChangelog() /*{{{*/ +{ + if (TemporaryDirectory.empty() == false) + { + unlink(DestFile.c_str()); + rmdir(TemporaryDirectory.c_str()); + } +} + /*}}}*/ + // AcqFile::pkgAcqFile - Constructor /*{{{*/ pkgAcqFile::pkgAcqFile(pkgAcquire * const Owner,string const &URI, HashStringList const &Hashes, unsigned long long const Size,string const &Dsc,string const &ShortDesc, diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index b6d569737..606fd4173 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -1031,6 +1031,120 @@ class pkgAcqArchive : public pkgAcquire::Item std::string &StoreFilename); }; /*}}}*/ +/** \brief Retrieve the changelog for the given version {{{ + * + * Downloads the changelog to a temporary file it will also remove again + * while it is deconstructed or downloads it to a named location. + */ +class pkgAcqChangelog : public pkgAcquire::Item +{ + void *d; + std::string TemporaryDirectory; + std::string const SrcName; + std::string const SrcVersion; + + public: + // we will never have hashes for changelogs. + // If you need verified ones, download the deb and extract the changelog. + virtual HashStringList GetExpectedHashes() const { return HashStringList(); } + virtual bool HashesRequired() const { return false; } + + // Specialized action members + virtual void Failed(std::string const &Message,pkgAcquire::MethodConfig const * const Cnf); + virtual void Done(std::string const &Message, HashStringList const &CalcHashes, + pkgAcquire::MethodConfig const * const Cnf); + virtual std::string DescURI() const {return Desc.URI;}; + + /** returns the URI to the changelog of this version + * + * @param Ver is the version to get the changelog for + * @return the URI which will be used to acquire the changelog + */ + static std::string URI(pkgCache::VerIterator const &Ver); + + /** returns the URI to the changelog of this version + * + * \param Rls is the Release file the package comes from + * \param Component in which the package resides, can be empty + * \param SrcName is the source package name + * \param SrcVersion is the source package version + * @return the URI which will be used to acquire the changelog + */ + static std::string URI(pkgCache::RlsFileIterator const &Rls, + char const * const Component, char const * const SrcName, + char const * const SrcVersion); + + /** returns the URI to the changelog of this version + * + * \param Template URI where CHANGEPATH has to be filled in + * \param Component in which the package resides, can be empty + * \param SrcName is the source package name + * \param SrcVersion is the source package version + * @return the URI which will be used to acquire the changelog + */ + static std::string URI(std::string const &Template, + char const * const Component, char const * const SrcName, + char const * const SrcVersion); + + /** returns the URI template for this release file + * + * \param Rls is a Release file + * @return the URI template to use for this release file + */ + static std::string URITemplate(pkgCache::RlsFileIterator const &Rls); + + /** \brief Create a new pkgAcqChangelog object. + * + * \param Owner The pkgAcquire object with which this object is + * associated. + * \param Ver is the version to get the changelog for + * \param DestDir The directory the file should be downloaded into. + * Will be an autocreated (and cleaned up) temporary directory if not set. + * \param DestFilename The filename the file should have in #DestDir + * Defaults to sourcepackagename.changelog if not set. + */ + pkgAcqChangelog(pkgAcquire * const Owner, pkgCache::VerIterator const &Ver, + std::string const &DestDir="", std::string const &DestFilename=""); + + /** \brief Create a new pkgAcqChangelog object. + * + * \param Owner The pkgAcquire object with which this object is + * associated. + * \param Rls is the Release file the package comes from + * \param Component in which the package resides, can be empty + * \param SrcName is the source package name + * \param SrcVersion is the source package version + * \param DestDir The directory the file should be downloaded into. + * Will be an autocreated (and cleaned up) temporary directory if not set. + * \param DestFilename The filename the file should have in #DestDir + * Defaults to sourcepackagename.changelog if not set. + */ + pkgAcqChangelog(pkgAcquire * const Owner, pkgCache::RlsFileIterator const &Rls, + char const * const Component, char const * const SrcName, char const * const SrcVersion, + std::string const &DestDir="", std::string const &DestFilename=""); + + /** \brief Create a new pkgAcqChangelog object. + * + * \param Owner The pkgAcquire object with which this object is + * associated. + * \param URI is to be used to get the changelog + * \param SrcName is the source package name + * \param SrcVersion is the source package version + * \param DestDir The directory the file should be downloaded into. + * Will be an autocreated (and cleaned up) temporary directory if not set. + * \param DestFilename The filename the file should have in #DestDir + * Defaults to sourcepackagename.changelog if not set. + */ + pkgAcqChangelog(pkgAcquire * const Owner, std::string const &URI, + char const * const SrcName, char const * const SrcVersion, + std::string const &DestDir="", std::string const &DestFilename=""); + + virtual ~pkgAcqChangelog(); + +private: + APT_HIDDEN void Init(std::string const &DestDir, std::string const &DestFilename); +}; + /*}}}*/ /** \brief Retrieve an arbitrary file to the current directory. {{{ * * The file is retrieved even if it is accessed via a URL type that diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc index e2239a906..96966b249 100644 --- a/apt-pkg/init.cc +++ b/apt-pkg/init.cc @@ -119,6 +119,10 @@ bool pkgInitConfig(Configuration &Cnf) Cnf.CndSet("APT::Acquire::Targets::deb-src::Sources::flatDescription", "$(SITE) $(RELEASE) Sources"); Cnf.CndSet("APT::Acquire::Targets::deb-src::Sources::Optional", false); + Cnf.CndSet("Acquire::Changelogs::URI::Origin::Debian", "http://metadata.ftp-master.debian.org/changelogs/CHANGEPATH_changelog"); + Cnf.CndSet("Acquire::Changelogs::URI::Origin::Ubuntu", "http://changelogs.ubuntu.com/changelogs/pool/CHANGEPATH/changelog"); + Cnf.CndSet("Acquire::Changelogs::URI::Origin::Ultimedia", "http://packages.ultimediaos.com/changelogs/pool/CHANGEPATH/changelog.txt"); + bool Res = true; // Read an alternate config file diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index a4cd3c377..184b51d23 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1410,196 +1410,70 @@ static bool DoBuildDep(CommandLine &CmdL) return true; } /*}}}*/ -// GetChangelogPath - return a path pointing to a changelog file or dir /*{{{*/ -// --------------------------------------------------------------------- -/* This returns a "path" string for the changelog url construction. - * Please note that its not complete, it either needs a "/changelog" - * appended (for the packages.debian.org/changelogs site) or a - * ".changelog" (for third party sites that store the changelog in the - * pool/ next to the deb itself) - * Example return: "pool/main/a/apt/apt_0.8.8ubuntu3" - */ -static string GetChangelogPath(CacheFile &Cache, - pkgCache::VerIterator Ver) -{ - pkgRecords Recs(Cache); - pkgRecords::Parser &rec=Recs.Lookup(Ver.FileList()); - string path = flNotFile(rec.FileName()); -#if APT_PKG_ABI >= 413 - path.append(Ver.SourcePkgName()); - path.append("_"); - path.append(StripEpoch(Ver.SourceVerStr())); -#else - string srcpkg = rec.SourcePkg().empty() ? Ver.ParentPkg().Name() : rec.SourcePkg(); - string ver = Ver.VerStr(); - // if there is a source version it always wins - if (rec.SourceVer() != "") - ver = rec.SourceVer(); - path += srcpkg + "_" + StripEpoch(ver); -#endif - return path; -} - /*}}}*/ -// GuessThirdPartyChangelogUri - return url /*{{{*/ -// --------------------------------------------------------------------- -/* Contruct a changelog file path for third party sites that do not use - * packages.debian.org/changelogs - * This simply uses the ArchiveURI() of the source pkg and looks for - * a .changelog file there, Example for "mediabuntu": - * apt-get changelog mplayer-doc: - * http://packages.medibuntu.org/pool/non-free/m/mplayer/mplayer_1.0~rc4~try1.dsfg1-1ubuntu1+medibuntu1.changelog - */ -static bool GuessThirdPartyChangelogUri(CacheFile &Cache, - pkgCache::VerIterator Ver, - string &out_uri) -{ - // get the binary deb server path - pkgCache::VerFileIterator Vf = Ver.FileList(); - if (Vf.end() == true) - return false; - pkgCache::PkgFileIterator F = Vf.File(); - pkgIndexFile *index; - pkgSourceList *SrcList = Cache.GetSourceList(); - if(SrcList->FindIndex(F, index) == false) - return false; - - // get archive uri for the binary deb - string path_without_dot_changelog = GetChangelogPath(Cache, Ver); - out_uri = index->ArchiveURI(path_without_dot_changelog + ".changelog"); - - // now strip away the filename and add srcpkg_srcver.changelog - return true; -} - /*}}}*/ -// DownloadChangelog - Download the changelog /*{{{*/ -// --------------------------------------------------------------------- -static bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, - pkgCache::VerIterator Ver, string targetfile) -/* Download a changelog file for the given package version to - * targetfile. This will first try the server from Apt::Changelogs::Server - * (http://packages.debian.org/changelogs by default) and if that gives - * a 404 tries to get it from the archive directly (see - * GuessThirdPartyChangelogUri for details how) - */ -{ - // make the server root configurable - string const server = _config->Find("Apt::Changelogs::Server", - "http://packages.debian.org/changelogs"); - string const path = GetChangelogPath(CacheFile, Ver); - string changelog_uri; - if (APT::String::Endswith(server, "/") == true) - strprintf(changelog_uri, "%s%s/changelog", server.c_str(), path.c_str()); - else - strprintf(changelog_uri, "%s/%s/changelog", server.c_str(), path.c_str()); - if (_config->FindB("APT::Get::Print-URIs", false) == true) - { - std::cout << '\'' << changelog_uri << '\'' << std::endl; - return true; - } - pkgCache::PkgIterator const Pkg = Ver.ParentPkg(); - - string descr; - strprintf(descr, _("Changelog for %s (%s)"), Pkg.Name(), changelog_uri.c_str()); - // queue it - pkgAcquire::Item const * itm = new pkgAcqFile(&Fetcher, changelog_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); - - // Disable drop-privs if "_apt" can not write to the target dir - CheckDropPrivsMustBeDisabled(Fetcher); - - // try downloading it, if that fails, try third-party-changelogs location - // FIXME: Fetcher.Run() is "Continue" even if I get a 404?!? - Fetcher.Run(); - if (itm->Status != pkgAcquire::Item::StatDone) - { - string third_party_uri; - if (GuessThirdPartyChangelogUri(CacheFile, Ver, third_party_uri)) - { - strprintf(descr, _("Changelog for %s (%s)"), Pkg.Name(), third_party_uri.c_str()); - itm = new pkgAcqFile(&Fetcher, third_party_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); - Fetcher.Run(); - } - } - - if (itm->Status == pkgAcquire::Item::StatDone) - return true; - - // error - return _error->Error("changelog download failed"); -} - /*}}}*/ // DoChangelog - Get changelog from the command line /*{{{*/ -// --------------------------------------------------------------------- static bool DoChangelog(CommandLine &CmdL) { CacheFile Cache; if (Cache.ReadOnlyOpen() == false) return false; - + APT::CacheSetHelper helper; APT::VersionList verset = APT::VersionList::FromCommandLine(Cache, CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper); if (verset.empty() == true) return false; pkgAcquire Fetcher; + AcqTextStatus Stat(std::cout, ScreenWidth,_config->FindI("quiet",0)); + Fetcher.SetLog(&Stat); - if (_config->FindB("APT::Get::Print-URIs", false) == true) + bool const downOnly = _config->FindB("APT::Get::Download-Only", false); + bool const printOnly = _config->FindB("APT::Get::Print-URIs", false); + + for (APT::VersionList::const_iterator Ver = verset.begin(); + Ver != verset.end(); + ++Ver) { - bool Success = true; - for (APT::VersionList::const_iterator Ver = verset.begin(); - Ver != verset.end(); ++Ver) - Success &= DownloadChangelog(Cache, Fetcher, Ver, ""); - return Success; + if (printOnly) + new pkgAcqChangelog(&Fetcher, Ver, "/dev/null"); + else if (downOnly) + new pkgAcqChangelog(&Fetcher, Ver, "."); + else + new pkgAcqChangelog(&Fetcher, Ver); } - AcqTextStatus Stat(std::cout, ScreenWidth,_config->FindI("quiet",0)); - Fetcher.SetLog(&Stat); + if (printOnly == false) + { + // Disable drop-privs if "_apt" can not write to the target dir + CheckDropPrivsMustBeDisabled(Fetcher); + if (_error->PendingError() == true) + return false; - bool const downOnly = _config->FindB("APT::Get::Download-Only", false); + bool Failed = false; + if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true) + return false; + } - char tmpname[100]; - const char* tmpdir = NULL; - if (downOnly == false) + if (downOnly == false || printOnly == true) { - std::string systemTemp = GetTempDir(); - snprintf(tmpname, sizeof(tmpname), "%s/apt-changelog-XXXXXX", - systemTemp.c_str()); - tmpdir = mkdtemp(tmpname); - if (tmpdir == NULL) - return _error->Errno("mkdtemp", "mkdtemp failed"); - - std::string const SandboxUser = _config->Find("APT::Sandbox::User"); - if (getuid() == 0 && SandboxUser.empty() == false) // if we aren't root, we can't chown, so don't try it + bool Failed = false; + for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); ++I) { - struct passwd const * const pw = getpwnam(SandboxUser.c_str()); - struct group const * const gr = getgrnam("root"); - if (pw != NULL && gr != NULL) + if (printOnly) { - // chown the tmp dir directory we use to the sandbox user - if(chown(tmpdir, pw->pw_uid, gr->gr_gid) != 0) - _error->WarningE("DoChangelog", "chown to %s:%s of directory %s failed", SandboxUser.c_str(), "root", tmpdir); + if ((*I)->ErrorText.empty() == false) + { + Failed = true; + _error->Error("%s", (*I)->ErrorText.c_str()); + } + else + cout << '\'' << (*I)->DescURI() << "' " << flNotDir((*I)->DestFile) << std::endl; } + else + DisplayFileInPager((*I)->DestFile); } + return Failed == false; } - for (APT::VersionList::const_iterator Ver = verset.begin(); - Ver != verset.end(); - ++Ver) - { - string changelogfile; - if (downOnly == false) - changelogfile.append(tmpname).append("/changelog"); - else - changelogfile.append(Ver.ParentPkg().Name()).append(".changelog"); - if (DownloadChangelog(Cache, Fetcher, Ver, changelogfile) && downOnly == false) - { - DisplayFileInPager(changelogfile); - // cleanup temp file - unlink(changelogfile.c_str()); - } - } - // clenaup tmp dir - if (tmpdir != NULL) - rmdir(tmpdir); return true; } /*}}}*/ diff --git a/doc/apt-get.8.xml b/doc/apt-get.8.xml index da077afa7..5b6788ed4 100644 --- a/doc/apt-get.8.xml +++ b/doc/apt-get.8.xml @@ -230,16 +230,12 @@ - changelog downloads a package changelog and displays - it through sensible-pager. The server name and base - directory is defined in the APT::Changelogs::Server - variable (e.g. packages.debian.org/changelogs for - Debian or changelogs.ubuntu.com/changelogs for - Ubuntu). - By default it displays the changelog for the version that is - installed. However, you can specify the same options as for - the command. - + changelog tries to download the + changelog of a package and displays it through + sensible-pager. By default it + displays the changelog for the version that is installed. + However, you can specify the same options as for the + command. diff --git a/doc/apt.conf.5.xml b/doc/apt.conf.5.xml index efe986ea8..7d5f7e9b3 100644 --- a/doc/apt.conf.5.xml +++ b/doc/apt.conf.5.xml @@ -618,6 +618,33 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";}; + scope + + Acquiring changelogs can only be done if an URI is known from where to get them. + Preferable the Release file indicates this in a 'Changelogs' field. If this isn't + available the Label/Origin field of the Release file is used to check if a + Acquire::Changelogs::URI::Label::LABEL or + Acquire::Changelogs::URI::Origin::ORIGIN option + exists and if so this value is taken. The value in the Release file can be overridden + with Acquire::Changelogs::URI::Override::Label::LABEL + or Acquire::Changelogs::URI::Override::Origin::ORIGIN. + + The value should be a normal URI to a text file, expect that package specific data is + replaced with the placeholder CHANGEPATH. The + value for it is: 1. if the package is from a component (e.g. main) + this is the first part otherwise it is omitted, 2. the first letter of source package name, + expect if the source package name starts with 'lib' in which case it will + be the first four letters. 3. The complete source package name. 4. the complete name again and + 5. the source version. + The first (if present), second, third and fourth part are separated by a slash ('/') + and between the fourth and fifth part is an underscore ('_'). + + The special value 'no' is available for this option indicating that + this source can't be used to acquire changelog files from. Another source will be tried + if available in this case. + + + diff --git a/doc/examples/configure-index b/doc/examples/configure-index index ef1ae056d..1339335fa 100644 --- a/doc/examples/configure-index +++ b/doc/examples/configure-index @@ -117,14 +117,6 @@ APT // does a ExecFork) Keep-Fds {}; - Changelogs - { - // server the provides the changelogs, the code will assume - // the changlogs are in the pool/ under a srcpkg_ver directory - // with the name "changelog" - Server "http://packages.debian.org/changelogs"; - }: - // control parameters for cron jobs by /etc/cron.daily/apt Periodic { @@ -305,6 +297,9 @@ Acquire "none"; "fr"; }; + + // Location of the changelogs with the placeholder CHANGEPATH (e.g. "main/a/apt/apt_1.1") + Changelogs::URI::Origin::Debian "http://metadata.ftp-master.debian.org/changelogs/CHANGEPATH_changelog"; }; // Directory layout diff --git a/test/integration/framework b/test/integration/framework index 7b03c09ef..1b99929e2 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -520,6 +520,12 @@ Package: $NAME" > debian/control buildsimplenativepackage() { local NAME="$1" + local NM + if [ "$(echo "$NAME" | cut -c 1-3)" = 'lib' ]; then + NM="$(echo "$NAME" | cut -c 1-4)" + else + NM="$(echo "$NAME" | cut -c 1)" + fi local ARCH="$2" local VERSION="$3" local RELEASE="${4:-unstable}" @@ -600,15 +606,15 @@ Package: $NAME" >> ${BUILDDIR}/debian/control (cd ${BUILDDIR}; dpkg-gencontrol -DArchitecture=$arch) (cd ${BUILDDIR}/debian/tmp; md5sum $(find usr/ -type f) > DEBIAN/md5sums) local LOG="${BUILDDIR}/../${NAME}_${VERSION}_${arch}.dpkg-deb.log" - # ensure the right permissions as dpkg-deb ensists + # ensure the right permissions as dpkg-deb insists chmod 755 ${BUILDDIR}/debian/tmp/DEBIAN testsuccess --nomsg dpkg-deb -Z${COMPRESS_TYPE} --build ${BUILDDIR}/debian/tmp ${BUILDDIR}/.. echo "pool/${NAME}_${VERSION}_${arch}.deb" >> ${BUILDDIR}/../${RELEASE}.${DISTSECTION}.pkglist done - mkdir -p ${BUILDDIR}/../${NAME}_${VERSION} - cp ${BUILDDIR}/debian/changelog ${BUILDDIR}/../${NAME}_${VERSION}/ - cp ${BUILDDIR}/debian/changelog ${BUILDDIR}/../${NAME}_${VERSION}.changelog + local CHANGEPATH="${BUILDDIR}/../${DISTSECTION}/${NM}/${NAME}/${NAME}_${VERSION}" + mkdir -p $CHANGEPATH + cp ${BUILDDIR}/debian/changelog $CHANGEPATH rm -rf "${BUILDDIR}" msgdone "info" } @@ -876,6 +882,7 @@ getcodenamefromsuite() { } getreleaseversionfromsuite() { true; } getlabelfromsuite() { true; } +getoriginfromsuite() { true; } generatereleasefiles() { # $1 is the Date header and $2 is the ValidUntil header to be set @@ -887,16 +894,21 @@ generatereleasefiles() { local CODENAME="$(getcodenamefromsuite $SUITE)" local VERSION="$(getreleaseversionfromsuite $SUITE)" local LABEL="$(getlabelfromsuite $SUITE)" + local ORIGIN="$(getoriginfromsuite $SUITE)" if [ -n "$VERSION" ]; then VERSION="-o APT::FTPArchive::Release::Version=${VERSION}" fi if [ -n "$LABEL" ]; then LABEL="-o APT::FTPArchive::Release::Label=${LABEL}" fi + if [ -n "$ORIGIN" ]; then + ORIGIN="-o APT::FTPArchive::Release::Origin=${ORIGIN}" + fi aptftparchive -qq release $dir \ -o APT::FTPArchive::Release::Suite="${SUITE}" \ -o APT::FTPArchive::Release::Codename="${CODENAME}" \ ${LABEL} \ + ${ORIGIN} \ ${VERSION} \ | sed -e '/0 Release$/ d' > $dir/Release # remove the self reference if [ "$SUITE" = "experimental" -o "$SUITE" = "experimental2" ]; then @@ -1450,9 +1462,9 @@ testfilestats() { msgpass else echo >&2 - ls -ld >&2 "$1" + ls -ld >&2 "$1" || true echo -n >&2 "stat(1) reports for $2: " - stat --format "$2" "$1" + stat --format "$2" "$1" || true msgfail fi } diff --git a/test/integration/test-apt-get-changelog b/test/integration/test-apt-get-changelog index 7e81c71b6..5fa8543b9 100755 --- a/test/integration/test-apt-get-changelog +++ b/test/integration/test-apt-get-changelog @@ -5,44 +5,98 @@ TESTDIR=$(readlink -f $(dirname $0)) . $TESTDIR/framework setupenvironment -configarchitecture "i386" +configarchitecture 'native' -buildsimplenativepackage 'apt' 'all' '1.0' 'stable' +buildsimplenativepackage 'foo' 'all' '1.0' 'stable' +buildsimplenativepackage 'libbar' 'all' '1.0' 'stable' + +getlabelfromsuite() { echo 'Testcases'; } +getoriginfromsuite() { echo 'Debian'; } setupaptarchive --no-update changetowebserver testsuccess aptget update -# simulate normal user with non-existent root-owned directories -rm -rf rootdir/var/cache/apt/archives/ -mkdir rootdir/var/cache/apt/archives/ -addtrap 'prefix' "chmod -f -R +w $PWD/rootdir/var/cache/apt/archives || true;" -chmod -R -w rootdir/var/cache/apt/archives +testsuccessequal "'http://metadata.ftp-master.debian.org/changelogs/main/f/foo/foo_1.0_changelog' foo.changelog +'http://metadata.ftp-master.debian.org/changelogs/main/libb/libbar/libbar_1.0_changelog' libbar.changelog" aptget changelog foo libbar --print-uris + +releasechanger() { + # modifying the Release files in lists… bad stuff. Good that this is only a test… + sed -i "s#^${1}: .*#${1}: ${2}#" $(find rootdir/var/lib/apt/lists -name '*Release') + rm -f rootdir/var/cache/apt/*.bin +} +releasechanger 'Origin' 'Ubuntu' +testsuccessequal "'http://changelogs.ubuntu.com/changelogs/pool/main/f/foo/foo_1.0/changelog' foo.changelog +'http://changelogs.ubuntu.com/changelogs/pool/main/libb/libbar/libbar_1.0/changelog' libbar.changelog" aptget changelog foo libbar --print-uris + +releasechanger 'Label' 'Debian' +testsuccessequal "'http://changelogs.ubuntu.com/changelogs/pool/main/f/foo/foo_1.0/changelog' foo.changelog +'http://changelogs.ubuntu.com/changelogs/pool/main/libb/libbar/libbar_1.0/changelog' libbar.changelog" aptget changelog foo libbar --print-uris + +testsuccessequal "'http://localhost:8080/main/f/foo/foo_1.0.changelog' foo.changelog +'http://localhost:8080/main/libb/libbar/libbar_1.0.changelog' libbar.changelog" aptget changelog foo libbar --print-uris -o Acquire::Changelogs::URI::Label::Debian='http://localhost:8080/CHANGEPATH.changelog' + +sed -i '/^Origin: / a\ +Changelogs: http://example.org/CHANGEPATH-changelog' $(find rootdir/var/lib/apt/lists -name '*Release') +rm -f rootdir/var/cache/apt/*.bin -echo 'Apt::Changelogs::Server "http://localhost:8080/";' > rootdir/etc/apt/apt.conf.d/changelog.conf +testsuccessequal "'http://example.org/main/f/foo/foo_1.0-changelog' foo.changelog +'http://example.org/main/libb/libbar/libbar_1.0-changelog' libbar.changelog" aptget changelog foo libbar --print-uris -o Acquire::Changelogs::URI::Label::Debian='http://localhost:8080/CHANGEPATH.changelog' -testsuccessequal "'http://localhost:8080/pool/apt_1.0/changelog'" aptget changelog apt --print-uris +testsuccessequal "'http://localhost:8080/main/f/foo/foo_1.0.changelog' foo.changelog +'http://localhost:8080/main/libb/libbar/libbar_1.0.changelog' libbar.changelog" aptget changelog foo libbar --print-uris -o Acquire::Changelogs::URI::Override::Label::Debian='http://localhost:8080/CHANGEPATH.changelog' -testsuccessequal "'http://localhost:8080/pool/apt_1.0/changelog' -'http://localhost:8080/pool/apt_1.0/changelog'" aptget changelog apt apt --print-uris +releasechanger 'Changelogs' 'no' +testequal 'E: Failed to fetch changelog:/foo.changelog Changelog unavailable for foo=1.0 +' aptget changelog foo -qq -d + +sed -i '/^Changelogs: / d' $(find rootdir/var/lib/apt/lists -name '*Release') +releasechanger 'Label' 'Testcases' + +echo 'Acquire::Changelogs::URI::Label::Testcases "http://localhost:8080/CHANGEPATH/change.txt";' > rootdir/etc/apt/apt.conf.d/changelog.conf +testsuccessequal "'http://localhost:8080/main/f/foo/foo_1.0/change.txt' foo.changelog +'http://localhost:8080/main/libb/libbar/libbar_1.0/change.txt' libbar.changelog" aptget changelog foo libbar --print-uris + +echo 'Acquire::Changelogs::URI::Label::Testcases "http://localhost:8080/pool/CHANGEPATH/changelog";' > rootdir/etc/apt/apt.conf.d/changelog.conf +testsuccessequal "'http://localhost:8080/pool/main/f/foo/foo_1.0/changelog' foo.changelog" aptget changelog foo --print-uris cd downloaded -testsuccess aptget changelog apt -qq -testfileequal '../rootdir/tmp/testsuccess.output' "$(cat ../aptarchive/pool/apt_1.0/changelog)" +testsuccess aptget changelog foo -qq +testfileequal '../rootdir/tmp/testsuccess.output' "$(cat ../aptarchive/pool/main/f/foo/foo_1.0/changelog)" + +testsuccess aptget changelog foo libbar -qq +testfileequal '../rootdir/tmp/testsuccess.output' "$(cat ../aptarchive/pool/main/f/foo/foo_1.0/changelog) +$(cat ../aptarchive/pool/main/libb/libbar/libbar_1.0/changelog)" + +testsuccess aptget changelog foo -d +testfilestats 'foo.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644" +testfileequal 'foo.changelog' "$(cat ../aptarchive/pool/main/f/foo/foo_1.0/changelog)" +rm -f foo.changelog -testsuccess aptget changelog apt -d -testfileequal 'apt.changelog' "$(cat ../aptarchive/pool/apt_1.0/changelog)" -testfilestats 'apt.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644" -rm -f apt.changelog ../aptarchive/pool/apt_1.0/changelog +testsuccess aptget changelog libbar foo -d +testfilestats 'libbar.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644" +testfilestats 'foo.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644" +testfileequal 'libbar.changelog' "$(cat ../aptarchive/pool/main/libb/libbar/libbar_1.0/changelog)" +testfileequal 'foo.changelog' "$(cat ../aptarchive/pool/main/f/foo/foo_1.0/changelog)" +rm -f libbar.changelog foo.changelog -testequal "$(cat ../aptarchive/pool/apt_1.0.changelog)" aptget changelog apt \ - -qq -o APT::Changelogs::Server='http://not-on-the-main-server:8080/' +# as such bogus, but can happen with multiple binaries from the same source +testsuccessequal "'http://localhost:8080/pool/main/f/foo/foo_1.0/changelog' foo.changelog +'http://localhost:8080/pool/main/f/foo/foo_1.0/changelog' foo.changelog" aptget changelog foo foo --print-uris +testsuccess aptget changelog foo foo -qq +testfileequal '../rootdir/tmp/testsuccess.output' "$(cat ../aptarchive/pool/main/f/foo/foo_1.0/changelog) +$(cat ../aptarchive/pool/main/f/foo/foo_1.0/changelog)" +testsuccess aptget changelog foo foo -d +testfilestats 'foo.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644" +testfileequal 'foo.changelog' "$(cat ../aptarchive/pool/main/f/foo/foo_1.0/changelog)" +rm -f foo.changelog -testsuccess aptget changelog apt -d -testfileequal 'apt.changelog' "$(cat ../aptarchive/pool/apt_1.0.changelog)" -testfilestats 'apt.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644" -rm -f apt.changelog ../aptarchive/pool/apt_1.0.changelog +# no CHANGEPATH in the URI +testequal 'E: Failed to fetch changelog:/foo.changelog Changelog unavailable for foo=1.0 +' aptget changelog foo -qq -d -o Acquire::Changelogs::URI::Label::Testcases='http://localhost:8080/change.txt' +testfailure test -e foo.changelog -testequal 'E: changelog download failed' aptget changelog apt -qq -d -o APT::Changelogs::Server='http://not-on-the-main-server:8080/' -testfailure test -e apt.changelog +testequal 'E: Failed to fetch http://localhost:8080/does/not/exist/main/f/foo/foo_1.0/change.txt Changelog unavailable for foo=1.0 (404 Not Found) +' aptget changelog foo -qq -d -o Acquire::Changelogs::URI::Label::Testcases='http://localhost:8080/does/not/exist/CHANGEPATH/change.txt' +testfailure test -e foo.changelog diff --git a/test/integration/test-bug-722207-print-uris-even-if-very-quiet b/test/integration/test-bug-722207-print-uris-even-if-very-quiet index 2cad929cc..e51d72ccd 100755 --- a/test/integration/test-bug-722207-print-uris-even-if-very-quiet +++ b/test/integration/test-bug-722207-print-uris-even-if-very-quiet @@ -12,6 +12,7 @@ insertpackage 'unstable' 'apt' 'all' '2' insertsource 'unstable' 'apt' 'all' '2' insertsource 'unstable' 'apt2' 'all' '1' +getoriginfromsuite() { echo 'Debian'; } setupaptarchive APTARCHIVE=$(readlink -f ./aptarchive) @@ -22,7 +23,7 @@ testsuccessequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.d testsuccessequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 " aptget download apt -qq --print-uris testsuccessequal "'file://${APTARCHIVE}/apt_2.dsc' apt_2.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e 'file://${APTARCHIVE}/apt_2.tar.gz' apt_2.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source apt -qq --print-uris -testsuccessequal "'http://packages.debian.org/changelogs/pool/main/apt/apt_2/changelog'" aptget changelog apt -qq --print-uris +testsuccessequal "'http://metadata.ftp-master.debian.org/changelogs/main/a/apt/apt_2_changelog' apt.changelog" aptget changelog apt -qq --print-uris testsuccessequal "'file://${APTARCHIVE}/apt_2.dsc' apt_2.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e 'file://${APTARCHIVE}/apt_2.tar.gz' apt_2.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e diff --git a/test/integration/test-bug-738785-switch-protocol b/test/integration/test-bug-738785-switch-protocol index f6336ffe3..539080200 100755 --- a/test/integration/test-bug-738785-switch-protocol +++ b/test/integration/test-bug-738785-switch-protocol @@ -10,6 +10,7 @@ configarchitecture "i386" buildsimplenativepackage 'apt' 'all' '1.0' 'stable' # setup http redirecting to https +getlabelfromsuite() { echo 'Testcases'; } setupaptarchive --no-update changetowebserver -o 'aptwebserver::redirect::replace::/redirectme/=https://localhost:4433/' \ -o 'aptwebserver::redirect::replace::/downgrademe/=http://localhost:8080/' \ @@ -20,10 +21,10 @@ sed -i -e 's#:4433/#:8080/redirectme#' -e 's# https:# http:#' rootdir/etc/apt/so testsuccess aptget update -o Debug::Acquire::http=1 -o Debug::Acquire::https=1 -o Debug::pkgAcquire::Worker=1 msgtest 'Test that the webserver does not answer' 'http requests' -downloadfile 'http://localhost:8080/pool/apt_1.0/changelog' changelog >/dev/null 2>&1 && msgfail || msgpass +downloadfile 'http://localhost:8080/pool/main/a/apt/apt_1.0/changelog' changelog >/dev/null 2>&1 && msgfail || msgpass -echo 'Apt::Changelogs::Server "http://localhost:8080/redirectme";' > rootdir/etc/apt/apt.conf.d/changelog.conf -testsuccessequal "'http://localhost:8080/redirectme/pool/apt_1.0/changelog'" aptget changelog apt --print-uris +echo 'Acquire::Changelogs::URI::Label::Testcases "http://localhost:8080/redirectme/pool/CHANGEPATH/changelog";' > rootdir/etc/apt/apt.conf.d/changelog.conf +testsuccessequal "'http://localhost:8080/redirectme/pool/main/a/apt/apt_1.0/changelog' apt.changelog" aptget changelog apt --print-uris cd downloaded testsuccess aptget changelog apt -d diff --git a/vendor/ubuntu/apt.conf-01-vendor-ubuntu b/vendor/ubuntu/apt.conf-01-vendor-ubuntu index c4092ff44..e69de29bb 100644 --- a/vendor/ubuntu/apt.conf-01-vendor-ubuntu +++ b/vendor/ubuntu/apt.conf-01-vendor-ubuntu @@ -1,6 +0,0 @@ -// Server information for apt-changelog -APT { - Changelogs { - Server "http://changelogs.ubuntu.com/changelogs"; - }; -}; -- cgit v1.2.3-70-g09d2 From 9d2a8a7388cf3b0bbbe92f6b0b30a533e1167f40 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 15 Jun 2015 23:06:56 +0200 Subject: condense parallel requests with the same hashes to one It shouldn't be too common, but sometimes people have multiple mirrors in the sources or otherwise repositories with the same content. Now that we gracefully can handle multiple requests to the same URI, we can also fold multiple requests with the same expected hashes into one. Note that this isn't trying to find oppertunities for merging, but just merges if it happens to encounter the oppertunity for it. This is most obvious in the new testcase actually as it needs to delay the action to give the acquire system enough time to figure out that they can be merged. --- apt-pkg/acquire.cc | 5 +- apt-private/acqprogress.cc | 6 +- test/integration/framework | 8 ++- test/integration/skip-aptwebserver | 25 ------- .../test-acquire-same-file-multiple-times | 4 +- .../test-acquire-same-repository-multiple-times | 81 ++++++++++++++++++++++ test/integration/test-apt-get-source | 42 ++++++----- test/integration/test-apt-get-source-arch | 23 +++--- test/integration/test-apt-get-source-multisources | 12 ++-- .../integration/test-apt-get-update-unauth-warning | 37 +++++++++- test/integration/test-apt-progress-fd | 4 -- test/integration/test-apt-update-ims | 18 +++++ .../test-bug-722207-print-uris-even-if-very-quiet | 12 ++-- test/integration/test-bug-738785-switch-protocol | 22 +++--- 14 files changed, 198 insertions(+), 101 deletions(-) delete mode 100755 test/integration/skip-aptwebserver create mode 100755 test/integration/test-acquire-same-repository-multiple-times (limited to 'test/integration/framework') diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index 14c8863dc..34afab181 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -680,9 +680,12 @@ bool pkgAcquire::Queue::Enqueue(ItemDesc &Item) { QItem **I = &Items; // move to the end of the queue and check for duplicates here + HashStringList const hsl = Item.Owner->GetExpectedHashes(); for (; *I != 0; I = &(*I)->Next) - if (Item.URI == (*I)->URI) + if (Item.URI == (*I)->URI || hsl == (*I)->Owner->GetExpectedHashes()) { + if (_config->FindB("Debug::pkgAcquire::Worker",false) == true) + std::cerr << " @ Queue: Action combined for " << Item.URI << " and " << (*I)->URI << std::endl; (*I)->Owners.push_back(Item.Owner); Item.Owner->Status = (*I)->Owner->Status; return false; diff --git a/apt-private/acqprogress.cc b/apt-private/acqprogress.cc index dc92e3b2a..f6c3d1204 100644 --- a/apt-private/acqprogress.cc +++ b/apt-private/acqprogress.cc @@ -116,14 +116,10 @@ void AcqTextStatus::Fail(pkgAcquire::ItemDesc &Itm) if (Quiet > 1) return; - // Ignore certain kinds of transient failures (bad code) - if (Itm.Owner->Status == pkgAcquire::Item::StatIdle) - return; - AssignItemID(Itm); clearLastLine(); - if (Itm.Owner->Status == pkgAcquire::Item::StatDone) + if (Itm.Owner->Status == pkgAcquire::Item::StatDone || Itm.Owner->Status == pkgAcquire::Item::StatIdle) { // TRANSLATOR: Very short word to be displayed for files in 'apt-get update' // which failed to download, but the error is ignored (compare "Err:") diff --git a/test/integration/framework b/test/integration/framework index 1b99929e2..d8f7567d9 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -245,7 +245,7 @@ setupenvironment() { echo "Dir \"${TMPWORKINGDIRECTORY}/rootdir\";" > aptconfig.conf 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 \"${METHODSDIR}\";" >> 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 if [ "$(id -u)" = '0' ]; then @@ -786,6 +786,8 @@ insertsource() { local SPATH="aptarchive/dists/${RELEASE}/main/source" mkdir -p $SPATH local FILE="${SPATH}/Sources" + local DSCFILE="${NAME}_${VERSION}.dsc" + local TARFILE="${NAME}_${VERSION}.tar.gz" echo "Package: $NAME Binary: $NAME Version: $VERSION @@ -793,8 +795,8 @@ Maintainer: Joe Sixpack Architecture: $ARCH" >> $FILE test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE echo "Files: - d41d8cd98f00b204e9800998ecf8427e 0 ${NAME}_${VERSION}.dsc - d41d8cd98f00b204e9800998ecf8427e 0 ${NAME}_${VERSION}.tar.gz + $(echo -n "$DSCFILE" | md5sum | cut -d' ' -f 1) $(echo -n "$DSCFILE" | wc -c) $DSCFILE + $(echo -n "$TARFILE" | md5sum | cut -d' ' -f 1) $(echo -n "$TARFILE" | wc -c) $TARFILE " >> $FILE } diff --git a/test/integration/skip-aptwebserver b/test/integration/skip-aptwebserver deleted file mode 100755 index 0622941ce..000000000 --- a/test/integration/skip-aptwebserver +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -set -e - -TESTDIR=$(readlink -f $(dirname $0)) -. $TESTDIR/framework - -setupenvironment -configarchitecture 'amd64' - -buildsimplenativepackage 'apt' 'all' '1.0' 'stable' - -setupaptarchive -changetowebserver - -rm -rf rootdir/var/lib/apt/lists -aptget update -qq -testequal 'Hit http://localhost stable InRelease -Hit http://localhost stable/main Sources -Hit http://localhost stable/main amd64 Packages -Hit http://localhost stable/main Translation-en -Reading package lists...' aptget update - -mv rootdir/var/lib/apt/lists/localhost* rootdir/var/lib/apt/lists/partial -aptget update - diff --git a/test/integration/test-acquire-same-file-multiple-times b/test/integration/test-acquire-same-file-multiple-times index d329a39cb..526765521 100755 --- a/test/integration/test-acquire-same-file-multiple-times +++ b/test/integration/test-acquire-same-file-multiple-times @@ -45,7 +45,7 @@ changetowebserver -o aptwebserver::redirect::replace::/foo2=/foo httpdown() { msgtest 'Downloading the same URI to different files' 'twice over http' - testsuccess --nomsg apthelper download-file http://localhost:8080/foo ./downloaded/foo1 '' http://localhost:8080/foo ./downloaded/foo2 '' -o Debug::pkgAcquire::Worker=1 + testsuccess --nomsg apthelper download-file http://localhost:8080/foo ./downloaded/foo1 '' http://localhost:8080/foo ./downloaded/foo2 '' -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::http=1 cp rootdir/tmp/testsuccess.output download.log testsuccess cmp $TESTDIR/framework ./downloaded/foo1 testsuccess cmp ./downloaded/foo1 ./downloaded/foo2 @@ -57,7 +57,7 @@ testrun 'httpdown' httpredirectdown() { msgtest 'Redirect leads' 'first URI to the second URI' - testsuccess --nomsg apthelper download-file http://localhost:8080/foo2 ./downloaded/foo1 '' http://localhost:8080/foo ./downloaded/foo2 '' -o Debug::pkgAcquire::Worker=1 + testsuccess --nomsg apthelper download-file http://localhost:8080/foo2 ./downloaded/foo1 '' http://localhost:8080/foo ./downloaded/foo2 '' -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::http=1 cp rootdir/tmp/testsuccess.output download.log testsuccess cmp $TESTDIR/framework ./downloaded/foo1 testsuccess cmp ./downloaded/foo1 ./downloaded/foo2 diff --git a/test/integration/test-acquire-same-repository-multiple-times b/test/integration/test-acquire-same-repository-multiple-times new file mode 100755 index 000000000..bfeaf88db --- /dev/null +++ b/test/integration/test-acquire-same-repository-multiple-times @@ -0,0 +1,81 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework +setupenvironment +configarchitecture 'amd64' + +TESTFILE="$TESTDIR/framework" +cp $TESTFILE aptarchive/foo +APTARCHIVE="$(readlink -f ./aptarchive)" + +getcodenamefromsuite() { echo "jessie"; } +buildsimplenativepackage 'foo' 'all' '1.0' 'stable' +setupaptarchive --no-update +ln -s "${APTARCHIVE}/dists/stable" "${APTARCHIVE}/dists/jessie" +for FILE in rootdir/etc/apt/sources.list.d/*-stable-* ; do + sed 's#stable#jessie#g' $FILE > $(echo "$FILE" | sed 's#stable#jessie#g') +done + +# install a slowed down file: otherwise its to fast to reproduce combining +NEWMETHODS="$(readlink -f rootdir)/usr/lib/apt/methods" +OLDMETHODS="$(readlink -f rootdir/usr/lib/apt/methods)" +rm $NEWMETHODS +mkdir $NEWMETHODS +for METH in $(find $OLDMETHODS ! -type d); do + ln -s $OLDMETHODS/$(basename $METH) $NEWMETHODS +done +rm $NEWMETHODS/file +cat >$NEWMETHODS/file < file.lst + testequal "$(find $(readlink -f ./rootdir/var/lib/apt/lists) -name '*_dists_*' \( ! -name '*InRelease' \) -type f | sort)" cat file.lst + testsuccess aptcache policy + testequal "foo: + Installed: (none) + Candidate: 1.0 + Version table: + 1.0 0 + 500 $1:$2 jessie/main amd64 Packages + 500 $1:$2 stable/main amd64 Packages" aptcache policy foo + testfailure aptcache show foo/unstable + testsuccess aptcache show foo/stable + testsuccess aptcache show foo/jessie +} + +tworepos 'file' "$APTARCHIVE" 'no partial' +testequal '12' grep -c '200%20URI%20Start' ./download.log +testequal '12' grep -c '201%20URI%20Done' ./download.log +testequal '6' grep -c '^ @ Queue: Action combined' ./download.log +tworepos 'file' "$APTARCHIVE" 'hit' +testequal '6' grep -c '200%20URI%20Start' ./download.log +testequal '6' grep -c '201%20URI%20Done' ./download.log +testequal '0' grep -c '^ @ Queue: Action combined' ./download.log +rm -rf rootdir/var/lib/apt/lists + +changetowebserver + +tworepos 'http' '//localhost:8080' 'no partial' +testequal '10' grep -c '200%20URI%20Start' ./download.log +testequal '10' grep -c '201%20URI%20Done' ./download.log +testequal '6' grep -c '^ @ Queue: Action combined' ./download.log +tworepos 'http' '//localhost:8080' 'hit' +testequal '2' grep -c '200%20URI%20Start' ./download.log +testequal '4' grep -c '201%20URI%20Done' ./download.log +testequal '0' grep -c '^ @ Queue: Action combined' ./download.log +rm -rf rootdir/var/lib/apt/lists diff --git a/test/integration/test-apt-get-source b/test/integration/test-apt-get-source index 9db24370f..22f01b997 100755 --- a/test/integration/test-apt-get-source +++ b/test/integration/test-apt-get-source @@ -34,43 +34,40 @@ APTARCHIVE=$(readlink -f ./aptarchive) # normal operation gets highest version number HEADER="Reading package lists... Building dependency tree..." +DOWNLOAD1="Need to get 0 B/25 B of source archives. +'file://${APTARCHIVE}/foo_1.0.dsc' foo_1.0.dsc 11 MD5Sum:b998e085e36cf162e6a33c2801318fef +'file://${APTARCHIVE}/foo_1.0.tar.gz' foo_1.0.tar.gz 14 MD5Sum:d46b9a02af8487cbeb49165540c88184" +DOWNLOAD2="Need to get 0 B/25 B of source archives. +'file://${APTARCHIVE}/foo_2.0.dsc' foo_2.0.dsc 11 MD5Sum:c0de572c6f8aa576c8ff78c81132ed55 +'file://${APTARCHIVE}/foo_2.0.tar.gz' foo_2.0.tar.gz 14 MD5Sum:e10bb487c375b2b938d27bd31c2d1f5f" testsuccessequal "$HEADER -Need to get 0 B of source archives. -'file://${APTARCHIVE}/foo_2.0.dsc' foo_2.0.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/foo_2.0.tar.gz' foo_2.0.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo +$DOWNLOAD2" aptget source -q --print-uris foo # select by release: suite testsuccessequal "$HEADER Selected version '1.0' (stable) for foo -Need to get 0 B of source archives. -'file://${APTARCHIVE}/foo_1.0.dsc' foo_1.0.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/foo_1.0.tar.gz' foo_1.0.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo/stable +$DOWNLOAD1" aptget source -q --print-uris foo/stable testsuccessequal "$HEADER Selected version '2.0' (unstable) for foo -Need to get 0 B of source archives. -'file://${APTARCHIVE}/foo_2.0.dsc' foo_2.0.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/foo_2.0.tar.gz' foo_2.0.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo/unstable +$DOWNLOAD2" aptget source -q --print-uris foo/unstable # select by release: codename testsuccessequal "$HEADER Selected version '2.0' (sid) for foo -Need to get 0 B of source archives. -'file://${APTARCHIVE}/foo_2.0.dsc' foo_2.0.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/foo_2.0.tar.gz' foo_2.0.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo/sid +$DOWNLOAD2" aptget source -q --print-uris foo/sid # select by version testsuccessequal "$HEADER -Need to get 0 B of source archives. -'file://${APTARCHIVE}/foo_1.0.dsc' foo_1.0.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/foo_1.0.tar.gz' foo_1.0.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo=1.0 +$DOWNLOAD1" aptget source -q --print-uris foo=1.0 # select by release with no binary package (Bug#731102) but ensure to get # highest version +DOWNLOAD01="Need to get 0 B/25 B of source archives. +'file://${APTARCHIVE}/foo_0.1.dsc' foo_0.1.dsc 11 MD5Sum:0811a4d85238056c613ea897f49f01af +'file://${APTARCHIVE}/foo_0.1.tar.gz' foo_0.1.tar.gz 14 MD5Sum:fa1ecb7a1a53e8e6f6551ca7db888a61" testsuccessequal "$HEADER Selected version '0.1' (wheezy) for foo -Need to get 0 B of source archives. -'file://${APTARCHIVE}/foo_0.1.dsc' foo_0.1.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/foo_0.1.tar.gz' foo_0.1.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo/wheezy +$DOWNLOAD01" aptget source -q --print-uris foo/wheezy # unavailable one testfailureequal "$HEADER @@ -78,11 +75,12 @@ E: Can not find version '9.9-not-there' of package 'foo' E: Unable to find a source package for foo" aptget source -q --print-uris foo=9.9-not-there # version and release +DOWNLOAD001="Need to get 0 B/29 B of source archives. +'file://${APTARCHIVE}/foo_0.0.1.dsc' foo_0.0.1.dsc 13 MD5Sum:6c819ebf0a21b1a480e1dbf6b8edfebd +'file://${APTARCHIVE}/foo_0.0.1.tar.gz' foo_0.0.1.tar.gz 16 MD5Sum:a3c7e1ac2159fc0faf522e110d6906fd" testsuccessequal "$HEADER -Need to get 0 B of source archives. -'file://${APTARCHIVE}/foo_0.0.1.dsc' foo_0.0.1.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/foo_0.0.1.tar.gz' foo_0.0.1.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris -t unstable foo=0.0.1 +$DOWNLOAD001" aptget source -q --print-uris -t unstable foo=0.0.1 testsuccessequal "$HEADER -Need to get 0 B of source archives. +Need to get 0 B/25 B of source archives. Fetch source foo" aptget source -q -s foo diff --git a/test/integration/test-apt-get-source-arch b/test/integration/test-apt-get-source-arch index c75798209..f54bb6012 100755 --- a/test/integration/test-apt-get-source-arch +++ b/test/integration/test-apt-get-source-arch @@ -28,31 +28,30 @@ APTARCHIVE=$(readlink -f ./aptarchive) HEADER="Reading package lists... Building dependency tree..." +DOWNLOAD10="Need to get 0 B/25 B of source archives. +'file://${APTARCHIVE}/foo_1.0.dsc' foo_1.0.dsc 11 MD5Sum:b998e085e36cf162e6a33c2801318fef +'file://${APTARCHIVE}/foo_1.0.tar.gz' foo_1.0.tar.gz 14 MD5Sum:d46b9a02af8487cbeb49165540c88184" # pick :amd64 testsuccessequal "$HEADER -Need to get 0 B of source archives. -'file://${APTARCHIVE}/foo_1.0.dsc' foo_1.0.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/foo_1.0.tar.gz' foo_1.0.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo:amd64 +$DOWNLOAD10" aptget source -q --print-uris foo:amd64 # pick :i386 testsuccessequal "$HEADER -Need to get 0 B of source archives. -'file://${APTARCHIVE}/foo_2.0.dsc' foo_2.0.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/foo_2.0.tar.gz' foo_2.0.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo:i386 +Need to get 0 B/25 B of source archives. +'file://${APTARCHIVE}/foo_2.0.dsc' foo_2.0.dsc 11 MD5Sum:c0de572c6f8aa576c8ff78c81132ed55 +'file://${APTARCHIVE}/foo_2.0.tar.gz' foo_2.0.tar.gz 14 MD5Sum:e10bb487c375b2b938d27bd31c2d1f5f" aptget source -q --print-uris foo:i386 # pick :i386 by release testsuccessequal "$HEADER Selected version '0.1' (oldstable) for foo -Need to get 0 B of source archives. -'file://${APTARCHIVE}/foo_0.1.dsc' foo_0.1.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/foo_0.1.tar.gz' foo_0.1.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo:i386/oldstable +Need to get 0 B/25 B of source archives. +'file://${APTARCHIVE}/foo_0.1.dsc' foo_0.1.dsc 11 MD5Sum:0811a4d85238056c613ea897f49f01af +'file://${APTARCHIVE}/foo_0.1.tar.gz' foo_0.1.tar.gz 14 MD5Sum:fa1ecb7a1a53e8e6f6551ca7db888a61" aptget source -q --print-uris foo:i386/oldstable # pick :i386 by version testsuccessequal "$HEADER -Need to get 0 B of source archives. -'file://${APTARCHIVE}/foo_1.0.dsc' foo_1.0.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/foo_1.0.tar.gz' foo_1.0.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -q --print-uris foo:i386=1.0 +$DOWNLOAD10" aptget source -q --print-uris foo:i386=1.0 # error on unknown arch testfailureequal "$HEADER diff --git a/test/integration/test-apt-get-source-multisources b/test/integration/test-apt-get-source-multisources index 03d0400a0..887a30685 100755 --- a/test/integration/test-apt-get-source-multisources +++ b/test/integration/test-apt-get-source-multisources @@ -20,11 +20,11 @@ APTARCHIVE=$(readlink -f ./aptarchive) HEADER="Reading package lists... Building dependency tree..." testsuccessequal "$HEADER -Need to get 0 B of source archives. -'file://${APTARCHIVE}/adduser_3.113+nmu3.dsc' adduser_3.113+nmu3.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/python-fll_0.9.11.dsc' python-fll_0.9.11.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -qdy --print-uris --dsc-only adduser=3.113 python-fll=0.9.11 +Need to get 0 B/43 B of source archives. +'file://${APTARCHIVE}/adduser_3.113+nmu3.dsc' adduser_3.113+nmu3.dsc 22 MD5Sum:255405ab5af211238ef53b7a1dd8ca4b +'file://${APTARCHIVE}/python-fll_0.9.11.dsc' python-fll_0.9.11.dsc 21 MD5Sum:740a9dbf02a295932f15b1415d0dc0df" aptget source -qdy --print-uris --dsc-only adduser=3.113 python-fll=0.9.11 testsuccessequal "$HEADER -Need to get 0 B of source archives. -'file://${APTARCHIVE}/python-fll_0.9.11.dsc' python-fll_0.9.11.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/adduser_3.113+nmu3.dsc' adduser_3.113+nmu3.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source -qdy --print-uris --dsc-only python-fll=0.9.11 adduser=3.113 +Need to get 0 B/43 B of source archives. +'file://${APTARCHIVE}/python-fll_0.9.11.dsc' python-fll_0.9.11.dsc 21 MD5Sum:740a9dbf02a295932f15b1415d0dc0df +'file://${APTARCHIVE}/adduser_3.113+nmu3.dsc' adduser_3.113+nmu3.dsc 22 MD5Sum:255405ab5af211238ef53b7a1dd8ca4b" aptget source -qdy --print-uris --dsc-only python-fll=0.9.11 adduser=3.113 diff --git a/test/integration/test-apt-get-update-unauth-warning b/test/integration/test-apt-get-update-unauth-warning index 5b81d56d2..fcabf244a 100755 --- a/test/integration/test-apt-get-update-unauth-warning +++ b/test/integration/test-apt-get-update-unauth-warning @@ -20,8 +20,10 @@ APTARCHIVE=$(readlink -f ./aptarchive) rm -f $APTARCHIVE/dists/unstable/*Release* # update without authenticated files leads to warning -testfailureequal "Ign:1 file:$APTARCHIVE unstable InRelease +testfailureequal "Get:1 file:$APTARCHIVE unstable InRelease +Ign:1 file:$APTARCHIVE unstable InRelease File not found +Get:2 file:$APTARCHIVE unstable Release Err:2 file:$APTARCHIVE unstable Release File not found W: The repository 'file:$APTARCHIVE unstable Release' does not have a Release file. This is deprecated, please contact the owner of the repository. @@ -36,10 +38,41 @@ filesize() { stat -c%s "$(aptget files --no-release-info --format '$(URI)' "Created-By: $1" | cut -d'/' -f 3- ).gz" } # allow override -testwarningequal "Ign:1 file:$APTARCHIVE unstable InRelease +#aptget update --allow-insecure-repositories -o Debug::pkgAcquire::worker=1 +#exit +testwarningequal "Get:1 file:$APTARCHIVE unstable InRelease +Ign:1 file:$APTARCHIVE unstable InRelease File not found +Get:2 file:$APTARCHIVE unstable Release Ign:2 file:$APTARCHIVE unstable Release File not found +Get:3 file:$APTARCHIVE unstable/main Sources +Ign:3 file:$APTARCHIVE unstable/main Sources + File not found +Get:4 file:$APTARCHIVE unstable/main i386 Packages +Ign:4 file:$APTARCHIVE unstable/main i386 Packages + File not found +Get:5 file:$APTARCHIVE unstable/main Translation-en +Ign:5 file:$APTARCHIVE unstable/main Translation-en + File not found +Get:3 file:$APTARCHIVE unstable/main Sources +Ign:3 file:$APTARCHIVE unstable/main Sources + File not found +Get:4 file:$APTARCHIVE unstable/main i386 Packages +Ign:4 file:$APTARCHIVE unstable/main i386 Packages + File not found +Get:5 file:$APTARCHIVE unstable/main Translation-en +Ign:5 file:$APTARCHIVE unstable/main Translation-en + File not found +Get:3 file:$APTARCHIVE unstable/main Sources +Ign:3 file:$APTARCHIVE unstable/main Sources + File not found +Get:4 file:$APTARCHIVE unstable/main i386 Packages +Ign:4 file:$APTARCHIVE unstable/main i386 Packages + File not found +Get:5 file:$APTARCHIVE unstable/main Translation-en +Ign:5 file:$APTARCHIVE unstable/main Translation-en + File not found Get:3 file:$APTARCHIVE unstable/main Sources [$(filesize 'Sources') B] Get:4 file:$APTARCHIVE unstable/main i386 Packages [$(filesize 'Packages') B] Get:5 file:$APTARCHIVE unstable/main Translation-en [$(filesize 'Translations') B] diff --git a/test/integration/test-apt-progress-fd b/test/integration/test-apt-progress-fd index 99b4ea050..e30d503cb 100755 --- a/test/integration/test-apt-progress-fd +++ b/test/integration/test-apt-progress-fd @@ -16,7 +16,6 @@ setupaptarchive exec 3> apt-progress.log testsuccess aptget install testing=0.1 -y -o APT::Status-Fd=3 testfileequal './apt-progress.log' 'dlstatus:1:0:Retrieving file 1 of 1 -dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:20:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Installing testing (amd64) @@ -33,7 +32,6 @@ pmstatus:dpkg-exec:83.3333:Running dpkg' exec 3> apt-progress.log testsuccess aptget install testing=0.8.15 -y -o APT::Status-Fd=3 testfileequal './apt-progress.log' 'dlstatus:1:0:Retrieving file 1 of 1 -dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:20:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Installing testing (amd64) @@ -50,7 +48,6 @@ pmstatus:dpkg-exec:83.3333:Running dpkg' exec 3> apt-progress.log testsuccess aptget install testing=0.8.15 --reinstall -y -o APT::Status-Fd=3 testfileequal './apt-progress.log' 'dlstatus:1:0:Retrieving file 1 of 1 -dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:20:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing:0:Installing testing (amd64) @@ -77,7 +74,6 @@ pmstatus:dpkg-exec:75:Running dpkg' exec 3> apt-progress.log testsuccess aptget install testing2:i386 -y -o APT::Status-Fd=3 testfileequal './apt-progress.log' 'dlstatus:1:0:Retrieving file 1 of 1 -dlstatus:1:0:Retrieving file 1 of 1 dlstatus:1:20:Retrieving file 1 of 1 pmstatus:dpkg-exec:0:Running dpkg pmstatus:testing2:0:Installing testing2 (i386) diff --git a/test/integration/test-apt-update-ims b/test/integration/test-apt-update-ims index 2b662171c..33b4ed1b9 100755 --- a/test/integration/test-apt-update-ims +++ b/test/integration/test-apt-update-ims @@ -134,6 +134,24 @@ EXPECT="Ign:1 http://localhost:8080 unstable InRelease 404 Not Found Ign:2 http://localhost:8080 unstable Release 404 Not Found +Ign:3 http://localhost:8080 unstable/main Sources + 404 Not Found +Ign:4 http://localhost:8080 unstable/main amd64 Packages + 404 Not Found +Ign:5 http://localhost:8080 unstable/main Translation-en + 404 Not Found +Ign:3 http://localhost:8080 unstable/main Sources + 404 Not Found +Ign:4 http://localhost:8080 unstable/main amd64 Packages + 404 Not Found +Ign:5 http://localhost:8080 unstable/main Translation-en + 404 Not Found +Ign:3 http://localhost:8080 unstable/main Sources + 404 Not Found +Ign:4 http://localhost:8080 unstable/main amd64 Packages + 404 Not Found +Ign:5 http://localhost:8080 unstable/main Translation-en + 404 Not Found Hit:3 http://localhost:8080 unstable/main Sources Hit:4 http://localhost:8080 unstable/main amd64 Packages Hit:5 http://localhost:8080 unstable/main Translation-en diff --git a/test/integration/test-bug-722207-print-uris-even-if-very-quiet b/test/integration/test-bug-722207-print-uris-even-if-very-quiet index e51d72ccd..1fa94de7d 100755 --- a/test/integration/test-bug-722207-print-uris-even-if-very-quiet +++ b/test/integration/test-bug-722207-print-uris-even-if-very-quiet @@ -21,11 +21,11 @@ testsuccessequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.d testsuccessequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 " aptget dist-upgrade -qq --print-uris testsuccessequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 " aptget install apt -qq --print-uris testsuccessequal "'file://${APTARCHIVE}/pool/main/apt/apt_2_all.deb' apt_2_all.deb 0 " aptget download apt -qq --print-uris -testsuccessequal "'file://${APTARCHIVE}/apt_2.dsc' apt_2.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/apt_2.tar.gz' apt_2.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source apt -qq --print-uris +testsuccessequal "'file://${APTARCHIVE}/apt_2.dsc' apt_2.dsc 9 MD5Sum:16ff470aaedad0f06fb951ed89ffdd3a +'file://${APTARCHIVE}/apt_2.tar.gz' apt_2.tar.gz 12 MD5Sum:ab2b546f59ff9e8f5cc7a2d987ff3373" aptget source apt -qq --print-uris testsuccessequal "'http://metadata.ftp-master.debian.org/changelogs/main/a/apt/apt_2_changelog' apt.changelog" aptget changelog apt -qq --print-uris -testsuccessequal "'file://${APTARCHIVE}/apt_2.dsc' apt_2.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/apt_2.tar.gz' apt_2.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/apt2_1.dsc' apt2_1.dsc 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e -'file://${APTARCHIVE}/apt2_1.tar.gz' apt2_1.tar.gz 0 MD5Sum:d41d8cd98f00b204e9800998ecf8427e" aptget source apt apt2 -qq --print-uris +testsuccessequal "'file://${APTARCHIVE}/apt_2.dsc' apt_2.dsc 9 MD5Sum:16ff470aaedad0f06fb951ed89ffdd3a +'file://${APTARCHIVE}/apt_2.tar.gz' apt_2.tar.gz 12 MD5Sum:ab2b546f59ff9e8f5cc7a2d987ff3373 +'file://${APTARCHIVE}/apt2_1.dsc' apt2_1.dsc 10 MD5Sum:4c572ce45f1e2bedbb30da7f5e1c241c +'file://${APTARCHIVE}/apt2_1.tar.gz' apt2_1.tar.gz 13 MD5Sum:2a96fec139f8722d93312a1ff8281232" aptget source apt apt2 -qq --print-uris diff --git a/test/integration/test-bug-738785-switch-protocol b/test/integration/test-bug-738785-switch-protocol index 539080200..e86f28824 100755 --- a/test/integration/test-bug-738785-switch-protocol +++ b/test/integration/test-bug-738785-switch-protocol @@ -39,18 +39,15 @@ cd - >/dev/null testsuccess aptget install apt -y testdpkginstalled 'apt' -# create a copy of all methods, expect https -eval `aptconfig shell METHODS Dir::Bin::Methods/d` -COPYMETHODS='usr/lib/apt/methods' -mv rootdir/${COPYMETHODS} rootdir/${COPYMETHODS}.bak -mkdir -p rootdir/$COPYMETHODS -cd rootdir/$COPYMETHODS -find $METHODS \! -type d | while read meth; do - ln -s $meth +# install a slowed down file: otherwise its to fast to reproduce combining +NEWMETHODS="$(readlink -f rootdir)/usr/lib/apt/methods" +OLDMETHODS="$(readlink -f rootdir/usr/lib/apt/methods)" +rm $NEWMETHODS +mkdir $NEWMETHODS +for METH in $(find $OLDMETHODS ! -type d); do + ln -s $OLDMETHODS/$(basename $METH) $NEWMETHODS done -rm https -cd - >/dev/null -echo "Dir::Bin::Methods \"${COPYMETHODS}\";" >> aptconfig.conf +rm $NEWMETHODS/https cd downloaded testfailureequal "E: The method driver $(readlink -f './../')/rootdir/usr/lib/apt/methods/https could not be found. @@ -59,8 +56,7 @@ testfailure test -e apt_1.0_all.deb cd - >/dev/null # revert to all methods -rm -rf rootdir/$COPYMETHODS -mv rootdir/${COPYMETHODS}.bak rootdir/${COPYMETHODS} +ln -s $OLDMETHODS/https $NEWMETHODS # check that downgrades from https to http are not allowed webserverconfig 'aptwebserver::support::http' 'true' -- cgit v1.2.3-70-g09d2 From 533fe3d13927798c17bdef84eba60ed9441d9608 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 15 Jun 2015 23:59:14 +0200 Subject: allow ratelimiting progress reporting for testcases Progress reports once in a while which is a bit to unpredictable for testcases, so we enforce a steady progress for them in the hope that this makes the tests (mostly test-apt-progress-fd) a bit more stable. Git-Dch: Ignore --- apt-pkg/acquire.cc | 14 ++++++++----- test/integration/framework | 23 ++++++++++++---------- .../test-acquire-same-repository-multiple-times | 2 +- 3 files changed, 23 insertions(+), 16 deletions(-) (limited to 'test/integration/framework') diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index 34afab181..5e5bec95c 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -955,7 +955,7 @@ std::string pkgAcquire::Queue::QItem::Custom600Headers() const /*{{{*/ // AcquireStatus::pkgAcquireStatus - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgAcquireStatus::pkgAcquireStatus() : d(NULL), Percent(0), Update(true), MorePulses(false) +pkgAcquireStatus::pkgAcquireStatus() : d(NULL), Percent(-1), Update(true), MorePulses(false) { Start(); } @@ -1054,13 +1054,17 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) Time = NewTime; } + double const OldPercent = Percent; // calculate the percentage, if we have too little data assume 1% if (TotalBytes > 0 && UnfetchedReleaseFiles) Percent = 0; - else + else // use both files and bytes because bytes can be unreliable - Percent = (0.8 * (CurrentBytes/float(TotalBytes)*100.0) + + Percent = (0.8 * (CurrentBytes/float(TotalBytes)*100.0) + 0.2 * (CurrentItems/float(TotalItems)*100.0)); + double const DiffPercent = Percent - OldPercent; + if (DiffPercent < 0.001 && _config->FindB("Acquire::Progress::Diffpercent", false) == true) + return true; int fd = _config->FindI("APT::Status-Fd",-1); if(fd > 0) @@ -1078,11 +1082,11 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) snprintf(msg,sizeof(msg), _("Retrieving file %li of %li (%s remaining)"), i, TotalItems, TimeToStr(ETA).c_str()); else snprintf(msg,sizeof(msg), _("Retrieving file %li of %li"), i, TotalItems); - + // build the status str status << "dlstatus:" << i << ":" << std::setprecision(3) << Percent - << ":" << msg + << ":" << msg << endl; std::string const dlstatus = status.str(); diff --git a/test/integration/framework b/test/integration/framework index d8f7567d9..5d949009f 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -273,16 +273,19 @@ EOF chmod +x "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" echo "Dir::Bin::dpkg \"${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg\";" > rootdir/etc/apt/apt.conf.d/99dpkg - if ! command dpkg --assert-multi-arch >/dev/null 2>&1; then - echo "DPKG::options:: \"--force-architecture\";" >> aptconfig.conf # Added to test multiarch before dpkg is ready for it… - fi - echo 'quiet::NoUpdate "true";' >> aptconfig.conf - echo 'quiet::NoStatistic "true";' >> aptconfig.conf - # too distracting for users, but helpful to detect changes - echo 'Acquire::Progress::Ignore::ShowErrorText "true";' >> aptconfig.conf - # 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";' >> aptconfig.conf + { + if ! command dpkg --assert-multi-arch >/dev/null 2>&1; then + echo "DPKG::options:: \"--force-architecture\";" # Added to test multiarch before dpkg is ready for it… + fi + echo 'quiet::NoUpdate "true";' + echo 'quiet::NoStatistic "true";' + # too distracting for users, but helpful to detect changes + echo 'Acquire::Progress::Ignore::ShowErrorText "true";' + echo 'Acquire::Progress::Diffpercent "true";' + # 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";' + } >> aptconfig.conf cp "${TESTDIRECTORY}/apt.pem" "${TMPWORKINGDIRECTORY}/rootdir/etc/webserver.pem" if [ "$(id -u)" = '0' ]; then diff --git a/test/integration/test-acquire-same-repository-multiple-times b/test/integration/test-acquire-same-repository-multiple-times index bfeaf88db..a46e0d73c 100755 --- a/test/integration/test-acquire-same-repository-multiple-times +++ b/test/integration/test-acquire-same-repository-multiple-times @@ -32,7 +32,7 @@ cat >$NEWMETHODS/file <