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). --- 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 +-- 7 files changed, 176 insertions(+), 67 deletions(-) create mode 100755 test/integration/test-apt-update-not-modified (limited to 'test/integration') 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 -- cgit v1.2.3-70-g09d2