]>
Commit | Line | Data |
---|---|---|
29b0d019 NP |
1 | #!/bin/sh |
2 | # | |
3 | # Copyright (c) 2008 Nicolas Pitre | |
4 | # | |
5 | ||
6 | test_description='resilience to pack corruptions with redundant objects' | |
7 | . ./test-lib.sh | |
8 | ||
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: | |
12 | # | |
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; | |
15 | # | |
16 | # 2) the bulk of object data is uncompressible so the text part remains | |
17 | # visible; | |
18 | # | |
19 | # 3) object header is always 2 bytes. | |
20 | ||
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 | |
30 | } | |
31 | ||
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 | |
42 | } | |
43 | ||
538cf6b6 NP |
44 | do_repack() { |
45 | pack=`printf "$blob_1\n$blob_2\n$blob_3\n" | | |
46 | git pack-objects $@ .git/objects/pack/pack` && | |
47 | pack=".git/objects/pack/pack-${pack}" | |
48 | } | |
49 | ||
29b0d019 NP |
50 | do_corrupt_object() { |
51 | ofs=`git show-index < ${pack}.idx | grep $1 | cut -f1 -d" "` && | |
52 | ofs=$(($ofs + $2)) && | |
53 | chmod +w ${pack}.pack && | |
538cf6b6 | 54 | dd of=${pack}.pack count=1 bs=1 conv=notrunc seek=$ofs && |
29b0d019 NP |
55 | test_must_fail git verify-pack ${pack}.pack |
56 | } | |
57 | ||
58 | test_expect_success \ | |
59 | 'initial setup validation' \ | |
60 | 'create_test_files && | |
61 | create_new_pack && | |
62 | git prune-packed && | |
63 | git cat-file blob $blob_1 > /dev/null && | |
64 | git cat-file blob $blob_2 > /dev/null && | |
65 | git cat-file blob $blob_3 > /dev/null' | |
66 | ||
67 | test_expect_success \ | |
68 | 'create corruption in header of first object' \ | |
538cf6b6 | 69 | 'do_corrupt_object $blob_1 0 < /dev/zero && |
29b0d019 NP |
70 | test_must_fail git cat-file blob $blob_1 > /dev/null && |
71 | test_must_fail git cat-file blob $blob_2 > /dev/null && | |
72 | test_must_fail git cat-file blob $blob_3 > /dev/null' | |
73 | ||
74 | test_expect_success \ | |
75 | '... but having a loose copy allows for full recovery' \ | |
76 | 'mv ${pack}.idx tmp && | |
77 | git hash-object -t blob -w file_1 && | |
78 | mv tmp ${pack}.idx && | |
79 | git cat-file blob $blob_1 > /dev/null && | |
80 | git cat-file blob $blob_2 > /dev/null && | |
81 | git cat-file blob $blob_3 > /dev/null' | |
82 | ||
83 | test_expect_success \ | |
84 | '... and loose copy of first delta allows for partial recovery' \ | |
85 | 'git prune-packed && | |
86 | test_must_fail git cat-file blob $blob_2 > /dev/null && | |
87 | mv ${pack}.idx tmp && | |
88 | git hash-object -t blob -w file_2 && | |
89 | mv tmp ${pack}.idx && | |
90 | test_must_fail git cat-file blob $blob_1 > /dev/null && | |
91 | git cat-file blob $blob_2 > /dev/null && | |
92 | git cat-file blob $blob_3 > /dev/null' | |
93 | ||
94 | test_expect_success \ | |
95 | 'create corruption in data of first object' \ | |
96 | 'create_new_pack && | |
97 | git prune-packed && | |
98 | chmod +w ${pack}.pack && | |
3015fa58 | 99 | perl -i.bak -pe "s/ base /abcdef/" ${pack}.pack && |
29b0d019 NP |
100 | test_must_fail git cat-file blob $blob_1 > /dev/null && |
101 | test_must_fail git cat-file blob $blob_2 > /dev/null && | |
102 | test_must_fail git cat-file blob $blob_3 > /dev/null' | |
103 | ||
104 | test_expect_success \ | |
105 | '... but having a loose copy allows for full recovery' \ | |
106 | 'mv ${pack}.idx tmp && | |
107 | git hash-object -t blob -w file_1 && | |
108 | mv tmp ${pack}.idx && | |
109 | git cat-file blob $blob_1 > /dev/null && | |
110 | git cat-file blob $blob_2 > /dev/null && | |
111 | git cat-file blob $blob_3 > /dev/null' | |
112 | ||
113 | test_expect_success \ | |
114 | '... and loose copy of second object allows for partial recovery' \ | |
115 | 'git prune-packed && | |
116 | test_must_fail git cat-file blob $blob_2 > /dev/null && | |
117 | mv ${pack}.idx tmp && | |
118 | git hash-object -t blob -w file_2 && | |
119 | mv tmp ${pack}.idx && | |
120 | test_must_fail git cat-file blob $blob_1 > /dev/null && | |
121 | git cat-file blob $blob_2 > /dev/null && | |
122 | git cat-file blob $blob_3 > /dev/null' | |
123 | ||
124 | test_expect_success \ | |
125 | 'create corruption in header of first delta' \ | |
126 | 'create_new_pack && | |
127 | git prune-packed && | |
538cf6b6 | 128 | do_corrupt_object $blob_2 0 < /dev/zero && |
29b0d019 NP |
129 | git cat-file blob $blob_1 > /dev/null && |
130 | test_must_fail git cat-file blob $blob_2 > /dev/null && | |
131 | test_must_fail git cat-file blob $blob_3 > /dev/null' | |
132 | ||
133 | test_expect_success \ | |
134 | '... but having a loose copy allows for full recovery' \ | |
135 | 'mv ${pack}.idx tmp && | |
136 | git hash-object -t blob -w file_2 && | |
137 | mv tmp ${pack}.idx && | |
138 | git cat-file blob $blob_1 > /dev/null && | |
139 | git cat-file blob $blob_2 > /dev/null && | |
140 | git cat-file blob $blob_3 > /dev/null' | |
141 | ||
538cf6b6 NP |
142 | test_expect_success \ |
143 | '... and then a repack "clears" the corruption' \ | |
144 | 'do_repack && | |
145 | git prune-packed && | |
146 | git verify-pack ${pack}.pack && | |
147 | git cat-file blob $blob_1 > /dev/null && | |
148 | git cat-file blob $blob_2 > /dev/null && | |
149 | git cat-file blob $blob_3 > /dev/null' | |
150 | ||
29b0d019 NP |
151 | test_expect_success \ |
152 | 'create corruption in data of first delta' \ | |
153 | 'create_new_pack && | |
154 | git prune-packed && | |
155 | chmod +w ${pack}.pack && | |
3015fa58 | 156 | perl -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack && |
29b0d019 NP |
157 | git cat-file blob $blob_1 > /dev/null && |
158 | test_must_fail git cat-file blob $blob_2 > /dev/null && | |
159 | test_must_fail git cat-file blob $blob_3 > /dev/null' | |
160 | ||
161 | test_expect_success \ | |
162 | '... but having a loose copy allows for full recovery' \ | |
163 | 'mv ${pack}.idx tmp && | |
164 | git hash-object -t blob -w file_2 && | |
165 | mv tmp ${pack}.idx && | |
166 | git cat-file blob $blob_1 > /dev/null && | |
167 | git cat-file blob $blob_2 > /dev/null && | |
168 | git cat-file blob $blob_3 > /dev/null' | |
169 | ||
538cf6b6 NP |
170 | test_expect_success \ |
171 | '... and then a repack "clears" the corruption' \ | |
172 | 'do_repack && | |
173 | git prune-packed && | |
174 | git verify-pack ${pack}.pack && | |
175 | git cat-file blob $blob_1 > /dev/null && | |
176 | git cat-file blob $blob_2 > /dev/null && | |
177 | git cat-file blob $blob_3 > /dev/null' | |
178 | ||
29b0d019 NP |
179 | test_expect_success \ |
180 | 'corruption in delta base reference of first delta (OBJ_REF_DELTA)' \ | |
181 | 'create_new_pack && | |
182 | git prune-packed && | |
538cf6b6 | 183 | do_corrupt_object $blob_2 2 < /dev/zero && |
29b0d019 NP |
184 | git cat-file blob $blob_1 > /dev/null && |
185 | test_must_fail git cat-file blob $blob_2 > /dev/null && | |
186 | test_must_fail git cat-file blob $blob_3 > /dev/null' | |
187 | ||
188 | test_expect_success \ | |
189 | '... but having a loose copy allows for full recovery' \ | |
190 | 'mv ${pack}.idx tmp && | |
191 | git hash-object -t blob -w file_2 && | |
192 | mv tmp ${pack}.idx && | |
193 | git cat-file blob $blob_1 > /dev/null && | |
194 | git cat-file blob $blob_2 > /dev/null && | |
195 | git cat-file blob $blob_3 > /dev/null' | |
196 | ||
197 | test_expect_success \ | |
538cf6b6 NP |
198 | '... and then a repack "clears" the corruption' \ |
199 | 'do_repack && | |
200 | git prune-packed && | |
201 | git verify-pack ${pack}.pack && | |
202 | git cat-file blob $blob_1 > /dev/null && | |
203 | git cat-file blob $blob_2 > /dev/null && | |
204 | git cat-file blob $blob_3 > /dev/null' | |
205 | ||
206 | test_expect_success \ | |
207 | 'corruption #0 in delta base reference of first delta (OBJ_OFS_DELTA)' \ | |
29b0d019 NP |
208 | 'create_new_pack --delta-base-offset && |
209 | git prune-packed && | |
538cf6b6 | 210 | do_corrupt_object $blob_2 2 < /dev/zero && |
29b0d019 NP |
211 | git cat-file blob $blob_1 > /dev/null && |
212 | test_must_fail git cat-file blob $blob_2 > /dev/null && | |
213 | test_must_fail git cat-file blob $blob_3 > /dev/null' | |
214 | ||
215 | test_expect_success \ | |
538cf6b6 | 216 | '... but having a loose copy allows for full recovery' \ |
29b0d019 | 217 | 'mv ${pack}.idx tmp && |
538cf6b6 NP |
218 | git hash-object -t blob -w file_2 && |
219 | mv tmp ${pack}.idx && | |
220 | git cat-file blob $blob_1 > /dev/null && | |
221 | git cat-file blob $blob_2 > /dev/null && | |
222 | git cat-file blob $blob_3 > /dev/null' | |
223 | ||
224 | test_expect_success \ | |
225 | '... and then a repack "clears" the corruption' \ | |
226 | 'do_repack --delta-base-offset && | |
227 | git prune-packed && | |
228 | git verify-pack ${pack}.pack && | |
229 | git cat-file blob $blob_1 > /dev/null && | |
230 | git cat-file blob $blob_2 > /dev/null && | |
231 | git cat-file blob $blob_3 > /dev/null' | |
232 | ||
233 | test_expect_success \ | |
234 | 'corruption #1 in delta base reference of first delta (OBJ_OFS_DELTA)' \ | |
235 | 'create_new_pack --delta-base-offset && | |
236 | git prune-packed && | |
a2d2c478 | 237 | printf "\001" | do_corrupt_object $blob_2 2 && |
538cf6b6 NP |
238 | git cat-file blob $blob_1 > /dev/null && |
239 | test_must_fail git cat-file blob $blob_2 > /dev/null && | |
240 | test_must_fail git cat-file blob $blob_3 > /dev/null' | |
241 | ||
242 | test_expect_success \ | |
243 | '... but having a loose copy allows for full recovery' \ | |
244 | 'mv ${pack}.idx tmp && | |
245 | git hash-object -t blob -w file_2 && | |
246 | mv tmp ${pack}.idx && | |
247 | git cat-file blob $blob_1 > /dev/null && | |
248 | git cat-file blob $blob_2 > /dev/null && | |
249 | git cat-file blob $blob_3 > /dev/null' | |
250 | ||
251 | test_expect_success \ | |
252 | '... and then a repack "clears" the corruption' \ | |
253 | 'do_repack --delta-base-offset && | |
254 | git prune-packed && | |
255 | git verify-pack ${pack}.pack && | |
256 | git cat-file blob $blob_1 > /dev/null && | |
257 | git cat-file blob $blob_2 > /dev/null && | |
258 | git cat-file blob $blob_3 > /dev/null' | |
259 | ||
260 | test_expect_success \ | |
261 | '... and a redundant pack allows for full recovery too' \ | |
262 | 'do_corrupt_object $blob_2 2 < /dev/zero && | |
263 | git cat-file blob $blob_1 > /dev/null && | |
264 | test_must_fail git cat-file blob $blob_2 > /dev/null && | |
265 | test_must_fail git cat-file blob $blob_3 > /dev/null && | |
266 | mv ${pack}.idx tmp && | |
29b0d019 NP |
267 | git hash-object -t blob -w file_1 && |
268 | git hash-object -t blob -w file_2 && | |
269 | printf "$blob_1\n$blob_2\n" | git pack-objects .git/objects/pack/pack && | |
270 | git prune-packed && | |
271 | mv tmp ${pack}.idx && | |
272 | git cat-file blob $blob_1 > /dev/null && | |
273 | git cat-file blob $blob_2 > /dev/null && | |
274 | git cat-file blob $blob_3 > /dev/null' | |
275 | ||
276 | test_done |