test case for pack resilience against corruptions
Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nicolas Pitre committed
Jun 23, 2008 at 21:24 UTC
29b0d01912cdf291ad2e9f6a4f143ee9e3c01ef9
1 file changed
+194
t/t5303-pack-corruption-resilience.sh
new
+194
@@ -0,0 +1,194 @@
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
+
44
+do_corrupt_object() {
45
+ ofs=`git show-index < ${pack}.idx | grep $1 | cut -f1 -d" "` &&
46
+ ofs=$(($ofs + $2)) &&
47
+ chmod +w ${pack}.pack &&
48
+ dd if=/dev/zero of=${pack}.pack count=1 bs=1 conv=notrunc seek=$ofs &&
49
+ test_must_fail git verify-pack ${pack}.pack
50
+}
51
+
52
+test_expect_success \
53
+ 'initial setup validation' \
54
+ 'create_test_files &&
55
+ create_new_pack &&
56
+ git prune-packed &&
57
+ git cat-file blob $blob_1 > /dev/null &&
58
+ git cat-file blob $blob_2 > /dev/null &&
59
+ git cat-file blob $blob_3 > /dev/null'
60
+
61
+test_expect_success \
62
+ 'create corruption in header of first object' \
63
+ 'do_corrupt_object $blob_1 0 &&
64
+ test_must_fail git cat-file blob $blob_1 > /dev/null &&
65
+ test_must_fail git cat-file blob $blob_2 > /dev/null &&
66
+ test_must_fail git cat-file blob $blob_3 > /dev/null'
67
+
68
+test_expect_success \
69
+ '... but having a loose copy allows for full recovery' \
70
+ 'mv ${pack}.idx tmp &&
71
+ git hash-object -t blob -w file_1 &&
72
+ mv tmp ${pack}.idx &&
73
+ git cat-file blob $blob_1 > /dev/null &&
74
+ git cat-file blob $blob_2 > /dev/null &&
75
+ git cat-file blob $blob_3 > /dev/null'
76
+
77
+test_expect_success \
78
+ '... and loose copy of first delta allows for partial recovery' \
79
+ 'git prune-packed &&
80
+ test_must_fail git cat-file blob $blob_2 > /dev/null &&
81
+ mv ${pack}.idx tmp &&
82
+ git hash-object -t blob -w file_2 &&
83
+ mv tmp ${pack}.idx &&
84
+ test_must_fail 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'
87
+
88
+test_expect_success \
89
+ 'create corruption in data of first object' \
90
+ 'create_new_pack &&
91
+ git prune-packed &&
92
+ chmod +w ${pack}.pack &&
93
+ perl -i -pe "s/ base /abcdef/" ${pack}.pack &&
94
+ test_must_fail git cat-file blob $blob_1 > /dev/null &&
95
+ test_must_fail git cat-file blob $blob_2 > /dev/null &&
96
+ test_must_fail git cat-file blob $blob_3 > /dev/null'
97
+
98
+test_expect_success \
99
+ '... but having a loose copy allows for full recovery' \
100
+ 'mv ${pack}.idx tmp &&
101
+ git hash-object -t blob -w file_1 &&
102
+ mv tmp ${pack}.idx &&
103
+ git cat-file blob $blob_1 > /dev/null &&
104
+ git cat-file blob $blob_2 > /dev/null &&
105
+ git cat-file blob $blob_3 > /dev/null'
106
+
107
+test_expect_success \
108
+ '... and loose copy of second object allows for partial recovery' \
109
+ 'git prune-packed &&
110
+ test_must_fail git cat-file blob $blob_2 > /dev/null &&
111
+ mv ${pack}.idx tmp &&
112
+ git hash-object -t blob -w file_2 &&
113
+ mv tmp ${pack}.idx &&
114
+ test_must_fail 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'
117
+
118
+test_expect_success \
119
+ 'create corruption in header of first delta' \
120
+ 'create_new_pack &&
121
+ git prune-packed &&
122
+ do_corrupt_object $blob_2 0 &&
123
+ git cat-file blob $blob_1 > /dev/null &&
124
+ test_must_fail git cat-file blob $blob_2 > /dev/null &&
125
+ test_must_fail git cat-file blob $blob_3 > /dev/null'
126
+
127
+test_expect_success \
128
+ '... but having a loose copy allows for full recovery' \
129
+ 'mv ${pack}.idx tmp &&
130
+ git hash-object -t blob -w file_2 &&
131
+ mv tmp ${pack}.idx &&
132
+ git cat-file blob $blob_1 > /dev/null &&
133
+ git cat-file blob $blob_2 > /dev/null &&
134
+ git cat-file blob $blob_3 > /dev/null'
135
+
136
+test_expect_success \
137
+ 'create corruption in data of first delta' \
138
+ 'create_new_pack &&
139
+ git prune-packed &&
140
+ chmod +w ${pack}.pack &&
141
+ perl -i -pe "s/ delta1 /abcdefgh/" ${pack}.pack &&
142
+ git cat-file blob $blob_1 > /dev/null &&
143
+ test_must_fail git cat-file blob $blob_2 > /dev/null &&
144
+ test_must_fail git cat-file blob $blob_3 > /dev/null'
145
+
146
+test_expect_success \
147
+ '... but having a loose copy allows for full recovery' \
148
+ 'mv ${pack}.idx tmp &&
149
+ git hash-object -t blob -w file_2 &&
150
+ mv tmp ${pack}.idx &&
151
+ git cat-file blob $blob_1 > /dev/null &&
152
+ git cat-file blob $blob_2 > /dev/null &&
153
+ git cat-file blob $blob_3 > /dev/null'
154
+
155
+test_expect_success \
156
+ 'corruption in delta base reference of first delta (OBJ_REF_DELTA)' \
157
+ 'create_new_pack &&
158
+ git prune-packed &&
159
+ do_corrupt_object $blob_2 2 &&
160
+ git cat-file blob $blob_1 > /dev/null &&
161
+ test_must_fail git cat-file blob $blob_2 > /dev/null &&
162
+ test_must_fail git cat-file blob $blob_3 > /dev/null'
163
+
164
+test_expect_success \
165
+ '... but having a loose copy allows for full recovery' \
166
+ 'mv ${pack}.idx tmp &&
167
+ git hash-object -t blob -w file_2 &&
168
+ mv tmp ${pack}.idx &&
169
+ git cat-file blob $blob_1 > /dev/null &&
170
+ git cat-file blob $blob_2 > /dev/null &&
171
+ git cat-file blob $blob_3 > /dev/null'
172
+
173
+test_expect_success \
174
+ 'corruption in delta base reference of first delta (OBJ_OFS_DELTA)' \
175
+ 'create_new_pack --delta-base-offset &&
176
+ git prune-packed &&
177
+ do_corrupt_object $blob_2 2 &&
178
+ git cat-file blob $blob_1 > /dev/null &&
179
+ test_must_fail git cat-file blob $blob_2 > /dev/null &&
180
+ test_must_fail git cat-file blob $blob_3 > /dev/null'
181
+
182
+test_expect_success \
183
+ '... and a redundant pack allows for full recovery too' \
184
+ 'mv ${pack}.idx tmp &&
185
+ git hash-object -t blob -w file_1 &&
186
+ git hash-object -t blob -w file_2 &&
187
+ printf "$blob_1\n$blob_2\n" | git pack-objects .git/objects/pack/pack &&
188
+ git prune-packed &&
189
+ mv tmp ${pack}.idx &&
190
+ git cat-file blob $blob_1 > /dev/null &&
191
+ git cat-file blob $blob_2 > /dev/null &&
192
+ git cat-file blob $blob_3 > /dev/null'
193
+
194
+test_done