Merge branch 'master' of git://repo.or.cz/alt-git
[git/dscho.git] / t / t5303-pack-corruption-resilience.sh
blob41c83e3477f48210e166781f512c3d8b87ebd72d
1 #!/bin/sh
3 # Copyright (c) 2008 Nicolas Pitre
6 test_description='resilience to pack corruptions with redundant objects'
7 . ./test-lib.sh
9 # Note: the test objects are created with knowledge of their pack encoding
10 # to ensure good code path coverage, and to facilitate direct alteration
11 # later on. The assumed characteristics are:
13 # 1) blob_2 is a delta with blob_1 for base and blob_3 is a delta with blob2
14 # for base, such that blob_3 delta depth is 2;
16 # 2) the bulk of object data is uncompressible so the text part remains
17 # visible;
19 # 3) object header is always 2 bytes.
21 create_test_files() {
22 test-genrandom "foo" 2000 > file_1 &&
23 test-genrandom "foo" 1800 > file_2 &&
24 test-genrandom "foo" 1800 > file_3 &&
25 echo " base " >> file_1 &&
26 echo " delta1 " >> file_2 &&
27 echo " delta delta2 " >> file_3 &&
28 test-genrandom "bar" 150 >> file_2 &&
29 test-genrandom "baz" 100 >> file_3
32 create_new_pack() {
33 rm -rf .git &&
34 git init &&
35 blob_1=`git hash-object -t blob -w file_1` &&
36 blob_2=`git hash-object -t blob -w file_2` &&
37 blob_3=`git hash-object -t blob -w file_3` &&
38 pack=`printf "$blob_1\n$blob_2\n$blob_3\n" |
39 git pack-objects $@ .git/objects/pack/pack` &&
40 pack=".git/objects/pack/pack-${pack}" &&
41 git verify-pack -v ${pack}.pack
44 do_repack() {
45 pack=`printf "$blob_1\n$blob_2\n$blob_3\n" |
46 git pack-objects $@ .git/objects/pack/packtmp` &&
47 packtmp=".git/objects/pack/packtmp-${pack}" &&
48 pack=".git/objects/pack/pack-${pack}" &&
49 mv "${packtmp}.pack" "${pack}.pack" &&
50 mv "${packtmp}.idx" "${pack}.idx"
53 do_corrupt_object() {
54 ofs=`git show-index < ${pack}.idx | grep $1 | cut -f1 -d" "` &&
55 ofs=$(($ofs + $2)) &&
56 chmod +w ${pack}.pack &&
57 dd of=${pack}.pack count=1 bs=1 conv=notrunc seek=$ofs &&
58 test_must_fail git verify-pack ${pack}.pack
61 printf '\0' > zero
63 test_expect_success \
64 'initial setup validation' \
65 'create_test_files &&
66 create_new_pack &&
67 git prune-packed &&
68 git cat-file blob $blob_1 > /dev/null &&
69 git cat-file blob $blob_2 > /dev/null &&
70 git cat-file blob $blob_3 > /dev/null'
72 test_expect_success \
73 'create corruption in header of first object' \
74 'do_corrupt_object $blob_1 0 < zero &&
75 test_must_fail git cat-file blob $blob_1 > /dev/null &&
76 test_must_fail git cat-file blob $blob_2 > /dev/null &&
77 test_must_fail git cat-file blob $blob_3 > /dev/null'
79 test_expect_success \
80 '... but having a loose copy allows for full recovery' \
81 'mv ${pack}.idx tmp &&
82 git hash-object -t blob -w file_1 &&
83 mv tmp ${pack}.idx &&
84 git cat-file blob $blob_1 > /dev/null &&
85 git cat-file blob $blob_2 > /dev/null &&
86 git cat-file blob $blob_3 > /dev/null'
88 test_expect_success \
89 '... and loose copy of first delta allows for partial recovery' \
90 'git prune-packed &&
91 test_must_fail git cat-file blob $blob_2 > /dev/null &&
92 mv ${pack}.idx tmp &&
93 git hash-object -t blob -w file_2 &&
94 mv tmp ${pack}.idx &&
95 test_must_fail git cat-file blob $blob_1 > /dev/null &&
96 git cat-file blob $blob_2 > /dev/null &&
97 git cat-file blob $blob_3 > /dev/null'
99 test_expect_success \
100 'create corruption in data of first object' \
101 'create_new_pack &&
102 git prune-packed &&
103 chmod +w ${pack}.pack &&
104 perl -i.bak -pe "s/ base /abcdef/" ${pack}.pack &&
105 test_must_fail git cat-file blob $blob_1 > /dev/null &&
106 test_must_fail git cat-file blob $blob_2 > /dev/null &&
107 test_must_fail git cat-file blob $blob_3 > /dev/null'
109 test_expect_success \
110 '... but having a loose copy allows for full recovery' \
111 'mv ${pack}.idx tmp &&
112 git hash-object -t blob -w file_1 &&
113 mv tmp ${pack}.idx &&
114 git cat-file blob $blob_1 > /dev/null &&
115 git cat-file blob $blob_2 > /dev/null &&
116 git cat-file blob $blob_3 > /dev/null'
118 test_expect_success \
119 '... and loose copy of second object allows for partial recovery' \
120 'git prune-packed &&
121 test_must_fail git cat-file blob $blob_2 > /dev/null &&
122 mv ${pack}.idx tmp &&
123 git hash-object -t blob -w file_2 &&
124 mv tmp ${pack}.idx &&
125 test_must_fail git cat-file blob $blob_1 > /dev/null &&
126 git cat-file blob $blob_2 > /dev/null &&
127 git cat-file blob $blob_3 > /dev/null'
129 test_expect_success \
130 'create corruption in header of first delta' \
131 'create_new_pack &&
132 git prune-packed &&
133 do_corrupt_object $blob_2 0 < zero &&
134 git cat-file blob $blob_1 > /dev/null &&
135 test_must_fail git cat-file blob $blob_2 > /dev/null &&
136 test_must_fail git cat-file blob $blob_3 > /dev/null'
138 test_expect_success \
139 '... but having a loose copy allows for full recovery' \
140 'mv ${pack}.idx tmp &&
141 git hash-object -t blob -w file_2 &&
142 mv tmp ${pack}.idx &&
143 git cat-file blob $blob_1 > /dev/null &&
144 git cat-file blob $blob_2 > /dev/null &&
145 git cat-file blob $blob_3 > /dev/null'
147 test_expect_success \
148 '... and then a repack "clears" the corruption' \
149 'do_repack &&
150 git prune-packed &&
151 git verify-pack ${pack}.pack &&
152 git cat-file blob $blob_1 > /dev/null &&
153 git cat-file blob $blob_2 > /dev/null &&
154 git cat-file blob $blob_3 > /dev/null'
156 test_expect_success \
157 'create corruption in data of first delta' \
158 'create_new_pack &&
159 git prune-packed &&
160 chmod +w ${pack}.pack &&
161 perl -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack &&
162 git cat-file blob $blob_1 > /dev/null &&
163 test_must_fail git cat-file blob $blob_2 > /dev/null &&
164 test_must_fail git cat-file blob $blob_3 > /dev/null'
166 test_expect_success \
167 '... but having a loose copy allows for full recovery' \
168 'mv ${pack}.idx tmp &&
169 git hash-object -t blob -w file_2 &&
170 mv tmp ${pack}.idx &&
171 git cat-file blob $blob_1 > /dev/null &&
172 git cat-file blob $blob_2 > /dev/null &&
173 git cat-file blob $blob_3 > /dev/null'
175 test_expect_success \
176 '... and then a repack "clears" the corruption' \
177 'do_repack &&
178 git prune-packed &&
179 git verify-pack ${pack}.pack &&
180 git cat-file blob $blob_1 > /dev/null &&
181 git cat-file blob $blob_2 > /dev/null &&
182 git cat-file blob $blob_3 > /dev/null'
184 test_expect_success \
185 'corruption in delta base reference of first delta (OBJ_REF_DELTA)' \
186 'create_new_pack &&
187 git prune-packed &&
188 do_corrupt_object $blob_2 2 < zero &&
189 git cat-file blob $blob_1 > /dev/null &&
190 test_must_fail git cat-file blob $blob_2 > /dev/null &&
191 test_must_fail git cat-file blob $blob_3 > /dev/null'
193 test_expect_success \
194 '... but having a loose copy allows for full recovery' \
195 'mv ${pack}.idx tmp &&
196 git hash-object -t blob -w file_2 &&
197 mv tmp ${pack}.idx &&
198 git cat-file blob $blob_1 > /dev/null &&
199 git cat-file blob $blob_2 > /dev/null &&
200 git cat-file blob $blob_3 > /dev/null'
202 test_expect_success \
203 '... and then a repack "clears" the corruption' \
204 'do_repack &&
205 git prune-packed &&
206 git verify-pack ${pack}.pack &&
207 git cat-file blob $blob_1 > /dev/null &&
208 git cat-file blob $blob_2 > /dev/null &&
209 git cat-file blob $blob_3 > /dev/null'
211 test_expect_success \
212 'corruption #0 in delta base reference of first delta (OBJ_OFS_DELTA)' \
213 'create_new_pack --delta-base-offset &&
214 git prune-packed &&
215 do_corrupt_object $blob_2 2 < zero &&
216 git cat-file blob $blob_1 > /dev/null &&
217 test_must_fail git cat-file blob $blob_2 > /dev/null &&
218 test_must_fail git cat-file blob $blob_3 > /dev/null'
220 test_expect_success \
221 '... but having a loose copy allows for full recovery' \
222 'mv ${pack}.idx tmp &&
223 git hash-object -t blob -w file_2 &&
224 mv tmp ${pack}.idx &&
225 git cat-file blob $blob_1 > /dev/null &&
226 git cat-file blob $blob_2 > /dev/null &&
227 git cat-file blob $blob_3 > /dev/null'
229 test_expect_success \
230 '... and then a repack "clears" the corruption' \
231 'do_repack --delta-base-offset &&
232 git prune-packed &&
233 git verify-pack ${pack}.pack &&
234 git cat-file blob $blob_1 > /dev/null &&
235 git cat-file blob $blob_2 > /dev/null &&
236 git cat-file blob $blob_3 > /dev/null'
238 test_expect_success \
239 'corruption #1 in delta base reference of first delta (OBJ_OFS_DELTA)' \
240 'create_new_pack --delta-base-offset &&
241 git prune-packed &&
242 printf "\001" | do_corrupt_object $blob_2 2 &&
243 git cat-file blob $blob_1 > /dev/null &&
244 test_must_fail git cat-file blob $blob_2 > /dev/null &&
245 test_must_fail git cat-file blob $blob_3 > /dev/null'
247 test_expect_success \
248 '... but having a loose copy allows for full recovery' \
249 'mv ${pack}.idx tmp &&
250 git hash-object -t blob -w file_2 &&
251 mv tmp ${pack}.idx &&
252 git cat-file blob $blob_1 > /dev/null &&
253 git cat-file blob $blob_2 > /dev/null &&
254 git cat-file blob $blob_3 > /dev/null'
256 test_expect_success \
257 '... and then a repack "clears" the corruption' \
258 'do_repack --delta-base-offset &&
259 git prune-packed &&
260 git verify-pack ${pack}.pack &&
261 git cat-file blob $blob_1 > /dev/null &&
262 git cat-file blob $blob_2 > /dev/null &&
263 git cat-file blob $blob_3 > /dev/null'
265 test_expect_success \
266 '... and a redundant pack allows for full recovery too' \
267 'do_corrupt_object $blob_2 2 < zero &&
268 git cat-file blob $blob_1 > /dev/null &&
269 test_must_fail git cat-file blob $blob_2 > /dev/null &&
270 test_must_fail git cat-file blob $blob_3 > /dev/null &&
271 mv ${pack}.idx tmp &&
272 git hash-object -t blob -w file_1 &&
273 git hash-object -t blob -w file_2 &&
274 printf "$blob_1\n$blob_2\n" | git pack-objects .git/objects/pack/pack &&
275 git prune-packed &&
276 mv tmp ${pack}.idx &&
277 git cat-file blob $blob_1 > /dev/null &&
278 git cat-file blob $blob_2 > /dev/null &&
279 git cat-file blob $blob_3 > /dev/null'
281 test_done