Merge branch 'master' of git://repo.or.cz/alt-git
[git/dscho.git] / t / t5303-pack-corruption-resilience.sh
blobb919db02ac6556bec4f1baa210646fcfb120dd59
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 zeros () {
45 while :; do
46 echo -n xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
47 done | tr x '\0'
50 do_repack() {
51 pack=`printf "$blob_1\n$blob_2\n$blob_3\n" |
52 git pack-objects $@ .git/objects/pack/pack` &&
53 pack=".git/objects/pack/pack-${pack}"
56 do_corrupt_object() {
57 ofs=`git show-index < ${pack}.idx | grep $1 | cut -f1 -d" "` &&
58 ofs=$(($ofs + $2)) &&
59 chmod +w ${pack}.pack &&
60 dd of=${pack}.pack count=1 bs=1 conv=notrunc seek=$ofs &&
61 test_must_fail git verify-pack ${pack}.pack
64 test_expect_success \
65 'initial setup validation' \
66 'create_test_files &&
67 create_new_pack &&
68 git prune-packed &&
69 git cat-file blob $blob_1 > /dev/null &&
70 git cat-file blob $blob_2 > /dev/null &&
71 git cat-file blob $blob_3 > /dev/null'
73 test_expect_success \
74 'create corruption in header of first object' \
75 'do_corrupt_object $blob_1 0 < /dev/zero &&
76 test_must_fail git cat-file blob $blob_1 > /dev/null &&
77 test_must_fail git cat-file blob $blob_2 > /dev/null &&
78 test_must_fail git cat-file blob $blob_3 > /dev/null'
80 test_expect_success \
81 '... but having a loose copy allows for full recovery' \
82 'mv ${pack}.idx tmp &&
83 git hash-object -t blob -w file_1 &&
84 mv tmp ${pack}.idx &&
85 git cat-file blob $blob_1 > /dev/null &&
86 git cat-file blob $blob_2 > /dev/null &&
87 git cat-file blob $blob_3 > /dev/null'
89 test_expect_success \
90 '... and loose copy of first delta allows for partial recovery' \
91 'git prune-packed &&
92 test_must_fail git cat-file blob $blob_2 > /dev/null &&
93 mv ${pack}.idx tmp &&
94 git hash-object -t blob -w file_2 &&
95 mv tmp ${pack}.idx &&
96 test_must_fail git cat-file blob $blob_1 > /dev/null &&
97 git cat-file blob $blob_2 > /dev/null &&
98 git cat-file blob $blob_3 > /dev/null'
100 test_expect_success \
101 'create corruption in data of first object' \
102 'create_new_pack &&
103 git prune-packed &&
104 chmod +w ${pack}.pack &&
105 perl -i.bak -pe "s/ base /abcdef/" ${pack}.pack &&
106 test_must_fail git cat-file blob $blob_1 > /dev/null &&
107 test_must_fail git cat-file blob $blob_2 > /dev/null &&
108 test_must_fail git cat-file blob $blob_3 > /dev/null'
110 test_expect_success \
111 '... but having a loose copy allows for full recovery' \
112 'mv ${pack}.idx tmp &&
113 git hash-object -t blob -w file_1 &&
114 mv tmp ${pack}.idx &&
115 git cat-file blob $blob_1 > /dev/null &&
116 git cat-file blob $blob_2 > /dev/null &&
117 git cat-file blob $blob_3 > /dev/null'
119 test_expect_success \
120 '... and loose copy of second object allows for partial recovery' \
121 'git prune-packed &&
122 test_must_fail git cat-file blob $blob_2 > /dev/null &&
123 mv ${pack}.idx tmp &&
124 git hash-object -t blob -w file_2 &&
125 mv tmp ${pack}.idx &&
126 test_must_fail git cat-file blob $blob_1 > /dev/null &&
127 git cat-file blob $blob_2 > /dev/null &&
128 git cat-file blob $blob_3 > /dev/null'
130 test_expect_success \
131 'create corruption in header of first delta' \
132 'create_new_pack &&
133 git prune-packed &&
134 do_corrupt_object $blob_2 0 < /dev/zero &&
135 git cat-file blob $blob_1 > /dev/null &&
136 test_must_fail git cat-file blob $blob_2 > /dev/null &&
137 test_must_fail git cat-file blob $blob_3 > /dev/null'
139 test_expect_success \
140 '... but having a loose copy allows for full recovery' \
141 'mv ${pack}.idx tmp &&
142 git hash-object -t blob -w file_2 &&
143 mv tmp ${pack}.idx &&
144 git cat-file blob $blob_1 > /dev/null &&
145 git cat-file blob $blob_2 > /dev/null &&
146 git cat-file blob $blob_3 > /dev/null'
148 test_expect_success \
149 '... and then a repack "clears" the corruption' \
150 'do_repack &&
151 git prune-packed &&
152 git verify-pack ${pack}.pack &&
153 git cat-file blob $blob_1 > /dev/null &&
154 git cat-file blob $blob_2 > /dev/null &&
155 git cat-file blob $blob_3 > /dev/null'
157 test_expect_success \
158 'create corruption in data of first delta' \
159 'create_new_pack &&
160 git prune-packed &&
161 chmod +w ${pack}.pack &&
162 perl -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack &&
163 git cat-file blob $blob_1 > /dev/null &&
164 test_must_fail git cat-file blob $blob_2 > /dev/null &&
165 test_must_fail git cat-file blob $blob_3 > /dev/null'
167 test_expect_success \
168 '... but having a loose copy allows for full recovery' \
169 'mv ${pack}.idx tmp &&
170 git hash-object -t blob -w file_2 &&
171 mv tmp ${pack}.idx &&
172 git cat-file blob $blob_1 > /dev/null &&
173 git cat-file blob $blob_2 > /dev/null &&
174 git cat-file blob $blob_3 > /dev/null'
176 test_expect_success \
177 '... and then a repack "clears" the corruption' \
178 'do_repack &&
179 git prune-packed &&
180 git verify-pack ${pack}.pack &&
181 git cat-file blob $blob_1 > /dev/null &&
182 git cat-file blob $blob_2 > /dev/null &&
183 git cat-file blob $blob_3 > /dev/null'
185 test_expect_success \
186 'corruption in delta base reference of first delta (OBJ_REF_DELTA)' \
187 'create_new_pack &&
188 git prune-packed &&
189 do_corrupt_object $blob_2 2 < /dev/zero &&
190 git cat-file blob $blob_1 > /dev/null &&
191 test_must_fail git cat-file blob $blob_2 > /dev/null &&
192 test_must_fail git cat-file blob $blob_3 > /dev/null'
194 test_expect_success \
195 '... but having a loose copy allows for full recovery' \
196 'mv ${pack}.idx tmp &&
197 git hash-object -t blob -w file_2 &&
198 mv tmp ${pack}.idx &&
199 git cat-file blob $blob_1 > /dev/null &&
200 git cat-file blob $blob_2 > /dev/null &&
201 git cat-file blob $blob_3 > /dev/null'
203 test_expect_success \
204 '... and then a repack "clears" the corruption' \
205 'do_repack &&
206 git prune-packed &&
207 git verify-pack ${pack}.pack &&
208 git cat-file blob $blob_1 > /dev/null &&
209 git cat-file blob $blob_2 > /dev/null &&
210 git cat-file blob $blob_3 > /dev/null'
212 test_expect_success \
213 'corruption #0 in delta base reference of first delta (OBJ_OFS_DELTA)' \
214 'create_new_pack --delta-base-offset &&
215 git prune-packed &&
216 do_corrupt_object $blob_2 2 < /dev/zero &&
217 git cat-file blob $blob_1 > /dev/null &&
218 test_must_fail git cat-file blob $blob_2 > /dev/null &&
219 test_must_fail git cat-file blob $blob_3 > /dev/null'
221 test_expect_success \
222 '... but having a loose copy allows for full recovery' \
223 'mv ${pack}.idx tmp &&
224 git hash-object -t blob -w file_2 &&
225 mv tmp ${pack}.idx &&
226 git cat-file blob $blob_1 > /dev/null &&
227 git cat-file blob $blob_2 > /dev/null &&
228 git cat-file blob $blob_3 > /dev/null'
230 test_expect_success \
231 '... and then a repack "clears" the corruption' \
232 'do_repack --delta-base-offset &&
233 git prune-packed &&
234 git verify-pack ${pack}.pack &&
235 git cat-file blob $blob_1 > /dev/null &&
236 git cat-file blob $blob_2 > /dev/null &&
237 git cat-file blob $blob_3 > /dev/null'
239 test_expect_success \
240 'corruption #1 in delta base reference of first delta (OBJ_OFS_DELTA)' \
241 'create_new_pack --delta-base-offset &&
242 git prune-packed &&
243 printf "\001" | do_corrupt_object $blob_2 2 &&
244 git cat-file blob $blob_1 > /dev/null &&
245 test_must_fail git cat-file blob $blob_2 > /dev/null &&
246 test_must_fail git cat-file blob $blob_3 > /dev/null'
248 test_expect_success \
249 '... but having a loose copy allows for full recovery' \
250 'mv ${pack}.idx tmp &&
251 git hash-object -t blob -w file_2 &&
252 mv tmp ${pack}.idx &&
253 git cat-file blob $blob_1 > /dev/null &&
254 git cat-file blob $blob_2 > /dev/null &&
255 git cat-file blob $blob_3 > /dev/null'
257 test_expect_success \
258 '... and then a repack "clears" the corruption' \
259 'do_repack --delta-base-offset &&
260 git prune-packed &&
261 git verify-pack ${pack}.pack &&
262 git cat-file blob $blob_1 > /dev/null &&
263 git cat-file blob $blob_2 > /dev/null &&
264 git cat-file blob $blob_3 > /dev/null'
266 test_expect_success \
267 '... and a redundant pack allows for full recovery too' \
268 'do_corrupt_object $blob_2 2 < /dev/zero &&
269 git cat-file blob $blob_1 > /dev/null &&
270 test_must_fail git cat-file blob $blob_2 > /dev/null &&
271 test_must_fail git cat-file blob $blob_3 > /dev/null &&
272 mv ${pack}.idx tmp &&
273 git hash-object -t blob -w file_1 &&
274 git hash-object -t blob -w file_2 &&
275 printf "$blob_1\n$blob_2\n" | git pack-objects .git/objects/pack/pack &&
276 git prune-packed &&
277 mv tmp ${pack}.idx &&
278 git cat-file blob $blob_1 > /dev/null &&
279 git cat-file blob $blob_2 > /dev/null &&
280 git cat-file blob $blob_3 > /dev/null'
282 test_done