]> git.saurik.com Git - apt.git/blob - test/integration/test-apt-update-rollback
Don't download "optional" files not in Release :/.
[apt.git] / test / integration / test-apt-update-rollback
1 #!/bin/sh
2 #
3 # test that apt-get update is transactional
4 #
5 set -e
6
7 avoid_ims_hit() {
8 touch -d '+1hour' aptarchive/dists/unstable/main/binary-i386/Packages*
9 touch -d '+1hour' aptarchive/dists/unstable/main/source/Sources*
10 touch -d '+1hour' aptarchive/dists/unstable/*Release*
11
12 touch -d '-1hour' rootdir/var/lib/apt/lists/*
13 }
14
15 create_fresh_archive()
16 {
17 rm -rf aptarchive/*
18 rm -f rootdir/var/lib/apt/lists/_* rootdir/var/lib/apt/lists/partial/*
19
20 insertpackage 'unstable' 'old' 'all' '1.0'
21
22 setupaptarchive --no-update
23 }
24
25 add_new_package() {
26 insertpackage 'unstable' 'new' 'all' '1.0'
27 insertsource 'unstable' 'new' 'all' '1.0'
28
29 setupaptarchive --no-update "$@"
30 }
31
32 break_repository_sources_index() {
33 mv "$APTARCHIVE/dists/unstable/main/source/Sources.gz" "$APTARCHIVE/dists/unstable/main/source/Sources.gz.orig"
34 printf 'xxx' > "$APTARCHIVE/dists/unstable/main/source/Sources"
35 compressfile "$APTARCHIVE/dists/unstable/main/source/Sources" "$@"
36 }
37
38 start_with_good_inrelease() {
39 create_fresh_archive
40 testsuccess aptget update
41 listcurrentlistsdirectory > lists.before
42 testsuccessequal 'dpkg/now 1.16.2+fake all [installed,local]
43 old/unstable 1.0 all' apt list -qq
44 }
45
46 test_inrelease_to_new_inrelease() {
47 msgmsg 'Test InRelease to new InRelease works fine'
48 start_with_good_inrelease
49
50 add_new_package '+1hour'
51 testsuccess aptget update -o Debug::Acquire::Transaction=1
52 testsuccessequal 'dpkg/now 1.16.2+fake all [installed,local]
53 new/unstable 1.0 all
54 old/unstable 1.0 all' apt list -qq
55 }
56
57 test_inrelease_to_broken_hash_reverts_all() {
58 msgmsg 'Test InRelease to broken InRelease reverts everything'
59 start_with_good_inrelease
60
61 add_new_package '+1hour'
62 # break the Sources file
63 break_repository_sources_index '+1hour'
64
65 # test the error condition
66 testfailureequal "E: Failed to fetch file:${APTARCHIVE}/dists/unstable/main/source/Sources.gz Hash Sum mismatch
67 Hashes of expected file:
68 - Filesize:$(stat -c '%s' 'aptarchive/dists/unstable/main/source/Sources.gz.orig') [weak]
69 - SHA256:$(sha256sum 'aptarchive/dists/unstable/main/source/Sources.gz.orig' | cut -d' ' -f 1)
70 Hashes of received file:
71 - SHA256:$(sha256sum 'aptarchive/dists/unstable/main/source/Sources.gz' | cut -d' ' -f 1)
72 - Filesize:$(stat -c '%s' 'aptarchive/dists/unstable/main/source/Sources.gz') [weak]
73 Last modification reported: $(lastmodification 'aptarchive/dists/unstable/main/source/Sources.gz')
74 Release file created at: $(releasefiledate 'aptarchive/dists/unstable/InRelease')
75 E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq
76 # ensure that the Packages file is also rolled back
77 testfileequal lists.before "$(listcurrentlistsdirectory)"
78 testfailureequal "E: Unable to locate package new" aptget install new -s -qq
79 }
80
81 test_inrelease_to_valid_release() {
82 msgmsg 'Test InRelease to valid Release'
83 start_with_good_inrelease
84
85 add_new_package '+1hour'
86 # switch to a unsigned repo now
87 rm -f "$APTARCHIVE/dists/unstable/InRelease" "$APTARCHIVE/dists/unstable/Release.gpg"
88
89 # update fails
90 testfailureequal "E: The repository 'file:${APTARCHIVE} unstable Release' is no longer signed." aptget update -qq
91
92 # test that security downgrade was not successful
93 testfileequal lists.before "$(listcurrentlistsdirectory)"
94 testsuccess aptget install old -s
95 testfailure aptget install new -s
96 testnotempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_InRelease'
97 testempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_Release'
98 }
99
100 test_inrelease_to_release_reverts_all() {
101 msgmsg 'Test InRelease to broken Release reverts everything'
102 start_with_good_inrelease
103
104 # switch to a unsigned repo now
105 add_new_package '+1hour'
106 rm -f "$APTARCHIVE/dists/unstable/InRelease" "$APTARCHIVE/dists/unstable/Release.gpg"
107
108 # break it
109 break_repository_sources_index '+1hour'
110
111 # ensure error
112 testfailureequal "E: The repository 'file:${APTARCHIVE} unstable Release' is no longer signed." aptget update -qq # -o Debug::acquire::transaction=1
113
114 # ensure that the Packages file is also rolled back
115 testfileequal lists.before "$(listcurrentlistsdirectory)"
116 testsuccess aptget install old -s
117 testfailure aptget install new -s
118 testnotempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_InRelease'
119 testempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_Release'
120 }
121
122 test_unauthenticated_to_invalid_inrelease() {
123 msgmsg 'Test UnAuthenticated to invalid InRelease reverts everything'
124 create_fresh_archive
125 rm -f "$APTARCHIVE/dists/unstable/InRelease" "$APTARCHIVE/dists/unstable/Release.gpg"
126
127 testwarning aptget update --allow-insecure-repositories
128 listcurrentlistsdirectory > lists.before
129 testfailureequal "WARNING: The following packages cannot be authenticated!
130 old
131 E: There were unauthenticated packages and -y was used without --allow-unauthenticated" aptget install -qq -y old
132
133 # go to authenticated but not correct
134 add_new_package '+1hour'
135 break_repository_sources_index '+1hour'
136
137 testfailureequal "E: Failed to fetch file:$APTARCHIVE/dists/unstable/main/source/Sources.gz Hash Sum mismatch
138 Hashes of expected file:
139 - Filesize:$(stat -c '%s' 'aptarchive/dists/unstable/main/source/Sources.gz.orig') [weak]
140 - SHA256:$(sha256sum 'aptarchive/dists/unstable/main/source/Sources.gz.orig' | cut -d' ' -f 1)
141 Hashes of received file:
142 - SHA256:$(sha256sum 'aptarchive/dists/unstable/main/source/Sources.gz' | cut -d' ' -f 1)
143 - Filesize:$(stat -c '%s' 'aptarchive/dists/unstable/main/source/Sources.gz') [weak]
144 Last modification reported: $(lastmodification 'aptarchive/dists/unstable/main/source/Sources.gz')
145 Release file created at: $(releasefiledate 'aptarchive/dists/unstable/InRelease')
146 E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq
147
148 testfileequal lists.before "$(listcurrentlistsdirectory)"
149 testempty find "${ROOTDIR}/var/lib/apt/lists" -maxdepth 1 -name '*_InRelease'
150 testfailureequal "WARNING: The following packages cannot be authenticated!
151 old
152 E: There were unauthenticated packages and -y was used without --allow-unauthenticated" aptget install -qq -y old
153 }
154
155 test_inrelease_to_unauth_inrelease() {
156 msgmsg 'Test InRelease to InRelease without good sig'
157 start_with_good_inrelease
158
159 signreleasefiles 'Marvin Paranoid'
160
161 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:${APTARCHIVE} unstable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E8525D47528144E2
162 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
163 W: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq
164
165 testfileequal lists.before "$(listcurrentlistsdirectory)"
166 testnotempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_InRelease'
167 }
168
169 test_inrelease_to_broken_gzip() {
170 msgmsg "Test InRelease to broken gzip"
171 start_with_good_inrelease
172
173 break_repository_sources_index '+1hour'
174 generatereleasefiles '+2hours'
175 signreleasefiles
176
177 # append junk at the end of the compressed file
178 echo "lala" >> "$APTARCHIVE/dists/unstable/main/source/Sources.gz"
179 touch -d '+2min' "$APTARCHIVE/dists/unstable/main/source/Sources.gz"
180 # remove uncompressed file to avoid fallback
181 rm "$APTARCHIVE/dists/unstable/main/source/Sources"
182
183 testfailure aptget update
184 testsuccess grep 'Hash Sum mismatch' rootdir/tmp/testfailure.output
185 testfileequal lists.before "$(listcurrentlistsdirectory)"
186 }
187
188 TESTDIR="$(readlink -f "$(dirname "$0")")"
189 . "$TESTDIR/framework"
190
191 setupenvironment
192 configarchitecture "i386"
193 export APT_DONT_SIGN='Release.gpg'
194
195 APTARCHIVE="$(readlink -f ./aptarchive)"
196 ROOTDIR="${TMPWORKINGDIRECTORY}/rootdir"
197 APTARCHIVE_LISTS="$(echo "$APTARCHIVE" | tr "/" "_" )"
198
199 # test the following cases:
200 # - InRelease -> broken InRelease revert to previous state
201 # - empty lists dir and broken remote leaves nothing on the system
202 # - InRelease -> hashsum mismatch for one file reverts all files to previous state
203 # - Release/Release.gpg -> hashsum mismatch
204 # - InRelease -> Release with hashsum mismatch revert entire state and kills Release
205 # - Release -> InRelease with broken Sig/Hash removes InRelease
206 # going from Release/Release.gpg -> InRelease and vice versa
207 # - unauthenticated -> invalid InRelease
208
209 # stuff to do:
210 # - ims-hit
211 # - gzip-index tests
212
213 test_inrelease_to_new_inrelease
214 test_inrelease_to_broken_hash_reverts_all
215 test_inrelease_to_valid_release
216 test_inrelease_to_release_reverts_all
217 test_unauthenticated_to_invalid_inrelease
218 test_inrelease_to_unauth_inrelease
219 test_inrelease_to_broken_gzip