##// END OF EJS Templates
revlog: add a failing variant of the the split + transaction test...
marmoute -
r51238:c185545a stable
parent child Browse files
Show More
@@ -1,241 +1,335 b''
1 Test correctness of revlog inline -> non-inline transition
1 Test correctness of revlog inline -> non-inline transition
2 ----------------------------------------------------------
2 ----------------------------------------------------------
3
3
4 Helper extension to intercept renames and kill process
4 Helper extension to intercept renames and kill process
5
5
6 $ cat > $TESTTMP/intercept_before_rename.py << EOF
6 $ cat > $TESTTMP/intercept_before_rename.py << EOF
7 > import os
7 > import os
8 > import signal
8 > import signal
9 > from mercurial import extensions, util
9 > from mercurial import extensions, util
10 >
10 >
11 > def extsetup(ui):
11 > def extsetup(ui):
12 > def close(orig, *args, **kwargs):
12 > def close(orig, *args, **kwargs):
13 > path = util.normpath(args[0]._atomictempfile__name)
13 > path = util.normpath(args[0]._atomictempfile__name)
14 > if path.endswith(b'/.hg/store/data/file.i'):
14 > if path.endswith(b'/.hg/store/data/file.i'):
15 > os.kill(os.getpid(), signal.SIGKILL)
15 > os.kill(os.getpid(), signal.SIGKILL)
16 > return orig(*args, **kwargs)
16 > return orig(*args, **kwargs)
17 > extensions.wrapfunction(util.atomictempfile, 'close', close)
17 > extensions.wrapfunction(util.atomictempfile, 'close', close)
18 > EOF
18 > EOF
19
19
20 $ cat > $TESTTMP/intercept_after_rename.py << EOF
21 > import os
22 > import signal
23 > from mercurial import extensions, util
24 >
25 > def extsetup(ui):
26 > def close(orig, *args, **kwargs):
27 > path = util.normpath(args[0]._atomictempfile__name)
28 > r = orig(*args, **kwargs)
29 > if path.endswith(b'/.hg/store/data/file.i'):
30 > os.kill(os.getpid(), signal.SIGKILL)
31 > return r
32 > extensions.wrapfunction(util.atomictempfile, 'close', close)
33 > EOF
34
20 $ cat > $TESTTMP/killme.py << EOF
35 $ cat > $TESTTMP/killme.py << EOF
21 > import os
36 > import os
22 > import signal
37 > import signal
23 >
38 >
24 > def killme(ui, repo, hooktype, **kwargs):
39 > def killme(ui, repo, hooktype, **kwargs):
25 > os.kill(os.getpid(), signal.SIGKILL)
40 > os.kill(os.getpid(), signal.SIGKILL)
26 > EOF
41 > EOF
27
42
28 setup a repository for tests
43 setup a repository for tests
29 ----------------------------
44 ----------------------------
30
45
31 $ cat >> $HGRCPATH << EOF
46 $ cat >> $HGRCPATH << EOF
32 > [format]
47 > [format]
33 > revlog-compression=none
48 > revlog-compression=none
34 > EOF
49 > EOF
35
50
36 $ hg init troffset-computation
51 $ hg init troffset-computation
37 $ cd troffset-computation
52 $ cd troffset-computation
38 $ printf '%20d' '1' > file
53 $ printf '%20d' '1' > file
39 $ hg commit -Aqma
54 $ hg commit -Aqma
40 $ printf '%1024d' '1' > file
55 $ printf '%1024d' '1' > file
41 $ hg commit -Aqmb
56 $ hg commit -Aqmb
42 $ printf '%20d' '1' > file
57 $ printf '%20d' '1' > file
43 $ hg commit -Aqmc
58 $ hg commit -Aqmc
44 $ dd if=/dev/zero of=file bs=1k count=128 > /dev/null 2>&1
59 $ dd if=/dev/zero of=file bs=1k count=128 > /dev/null 2>&1
45 $ hg commit -AqmD
60 $ hg commit -AqmD
46
61
47 Reference size:
62 Reference size:
48 $ f -s file
63 $ f -s file
49 file: size=131072
64 file: size=131072
50 $ f -s .hg/store/data/file*
65 $ f -s .hg/store/data/file*
51 .hg/store/data/file.d: size=132139
66 .hg/store/data/file.d: size=132139
52 .hg/store/data/file.i: size=256
67 .hg/store/data/file.i: size=256
53
68
54 $ cd ..
69 $ cd ..
55
70
56
71
57 Test a hard crash after the file was split but before the transaction was committed
72 Test a hard crash after the file was split but before the transaction was committed
58 ===================================================================================
73 ===================================================================================
59
74
60 Test offset computation to correctly factor in the index entries themselves.
75 Test offset computation to correctly factor in the index entries themselves.
61 Also test that the new data size has the correct size if the transaction is aborted
76 Also test that the new data size has the correct size if the transaction is aborted
62 after the index has been replaced.
77 after the index has been replaced.
63
78
64 Test repo has commits a, b, c, D, where D is large (grows the revlog enough that it
79 Test repo has commits a, b, c, D, where D is large (grows the revlog enough that it
65 transitions to non-inline storage). The clone initially has changes a, b
80 transitions to non-inline storage). The clone initially has changes a, b
66 and will transition to non-inline storage when adding c, D.
81 and will transition to non-inline storage when adding c, D.
67
82
68 If the transaction adding c, D is rolled back, then we don't undo the revlog split,
83 If the transaction adding c, D is rolled back, then we don't undo the revlog split,
69 but truncate the index and the data to remove both c and D.
84 but truncate the index and the data to remove both c and D.
70
85
71
86
72 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy
87 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy
73 $ cd troffset-computation-copy
88 $ cd troffset-computation-copy
74
89
75 Reference size:
90 Reference size:
76 $ f -s file
91 $ f -s file
77 file: size=1024
92 file: size=1024
78 $ f -s .hg/store/data/file*
93 $ f -s .hg/store/data/file*
79 .hg/store/data/file.i: size=1174
94 .hg/store/data/file.i: size=1174
80
95
81 $ cat > .hg/hgrc <<EOF
96 $ cat > .hg/hgrc <<EOF
82 > [hooks]
97 > [hooks]
83 > pretxnchangegroup = python:$TESTTMP/killme.py:killme
98 > pretxnchangegroup = python:$TESTTMP/killme.py:killme
84 > EOF
99 > EOF
85 #if chg
100 #if chg
86 $ hg pull ../troffset-computation
101 $ hg pull ../troffset-computation
87 pulling from ../troffset-computation
102 pulling from ../troffset-computation
88 [255]
103 [255]
89 #else
104 #else
90 $ hg pull ../troffset-computation
105 $ hg pull ../troffset-computation
91 pulling from ../troffset-computation
106 pulling from ../troffset-computation
92 Killed
107 Killed
93 [137]
108 [137]
94 #endif
109 #endif
95
110
96
111
97 The revlog have been split on disk
112 The revlog have been split on disk
98
113
99 $ f -s .hg/store/data/file*
114 $ f -s .hg/store/data/file*
100 .hg/store/data/file.d: size=132139
115 .hg/store/data/file.d: size=132139
101 .hg/store/data/file.i: size=256
116 .hg/store/data/file.i: size=256
102
117
103 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file | tail -1
118 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file | tail -1
104 data/file.i 128
119 data/file.i 128
105
120
106 The first file.i entry should match the "Reference size" above.
121 The first file.i entry should match the "Reference size" above.
107 The first file.d entry is the temporary record during the split,
122 The first file.d entry is the temporary record during the split,
108
123
109 The second entry after the split happened. The sum of the second file.d
124 The second entry after the split happened. The sum of the second file.d
110 and the second file.i entry should match the first file.i entry.
125 and the second file.i entry should match the first file.i entry.
111
126
112 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
127 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
113 data/file.i 1174
128 data/file.i 1174
114 data/file.d 0
129 data/file.d 0
115 data/file.d 1046
130 data/file.d 1046
116 data/file.i 128
131 data/file.i 128
117 $ hg recover
132 $ hg recover
118 rolling back interrupted transaction
133 rolling back interrupted transaction
119 (verify step skipped, run `hg verify` to check your repository content)
134 (verify step skipped, run `hg verify` to check your repository content)
120 $ f -s .hg/store/data/file*
135 $ f -s .hg/store/data/file*
121 .hg/store/data/file.d: size=1046
136 .hg/store/data/file.d: size=1046
122 .hg/store/data/file.i: size=128
137 .hg/store/data/file.i: size=128
123 $ hg tip
138 $ hg tip
124 changeset: 1:cfa8d6e60429
139 changeset: 1:cfa8d6e60429
125 tag: tip
140 tag: tip
126 user: test
141 user: test
127 date: Thu Jan 01 00:00:00 1970 +0000
142 date: Thu Jan 01 00:00:00 1970 +0000
128 summary: b
143 summary: b
129
144
130 $ hg verify -q
145 $ hg verify -q
131 warning: revlog 'data/file.d' not in fncache!
146 warning: revlog 'data/file.d' not in fncache!
132 1 warnings encountered!
147 1 warnings encountered!
133 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
148 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
134 $ hg debugrebuildfncache --only-data
149 $ hg debugrebuildfncache --only-data
135 adding data/file.d
150 adding data/file.d
136 1 items added, 0 removed from fncache
151 1 items added, 0 removed from fncache
137 $ hg verify -q
152 $ hg verify -q
138 $ cd ..
153 $ cd ..
139
154
140 Test a hard crash right before the index is move into place
155 Test a hard crash right before the index is move into place
141 ===========================================================
156 ===========================================================
142
157
143 Now retry the procedure but intercept the rename of the index and check that
158 Now retry the procedure but intercept the rename of the index and check that
144 the journal does not contain the new index size. This demonstrates the edge case
159 the journal does not contain the new index size. This demonstrates the edge case
145 where the data file is left as garbage.
160 where the data file is left as garbage.
146
161
147 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy2
162 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy2
148 $ cd troffset-computation-copy2
163 $ cd troffset-computation-copy2
149
164
150 Reference size:
165 Reference size:
151 $ f -s file
166 $ f -s file
152 file: size=1024
167 file: size=1024
153 $ f -s .hg/store/data/file*
168 $ f -s .hg/store/data/file*
154 .hg/store/data/file.i: size=1174
169 .hg/store/data/file.i: size=1174
155
170
156 $ cat > .hg/hgrc <<EOF
171 $ cat > .hg/hgrc <<EOF
157 > [extensions]
172 > [extensions]
158 > intercept_rename = $TESTTMP/intercept_before_rename.py
173 > intercept_rename = $TESTTMP/intercept_before_rename.py
159 > [hooks]
174 > [hooks]
160 > pretxnchangegroup = python:$TESTTMP/killme.py:killme
175 > pretxnchangegroup = python:$TESTTMP/killme.py:killme
161 > EOF
176 > EOF
162 #if chg
177 #if chg
163 $ hg pull ../troffset-computation
178 $ hg pull ../troffset-computation
164 pulling from ../troffset-computation
179 pulling from ../troffset-computation
165 [255]
180 [255]
166 #else
181 #else
167 $ hg pull ../troffset-computation
182 $ hg pull ../troffset-computation
168 pulling from ../troffset-computation
183 pulling from ../troffset-computation
169 Killed
184 Killed
170 [137]
185 [137]
171 #endif
186 #endif
172
187
173 The data file is created, but the revlog is still inline
188 The data file is created, but the revlog is still inline
174
189
175 $ f -s .hg/store/data/file*
190 $ f -s .hg/store/data/file*
176 .hg/store/data/file.d: size=132139
191 .hg/store/data/file.d: size=132139
177 .hg/store/data/file.i: size=132395
192 .hg/store/data/file.i: size=132395
178
193
179 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
194 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
180 data/file.i 1174
195 data/file.i 1174
181 data/file.d 0
196 data/file.d 0
182 data/file.d 1046
197 data/file.d 1046
183
198
184 $ hg recover
199 $ hg recover
185 rolling back interrupted transaction
200 rolling back interrupted transaction
186 (verify step skipped, run `hg verify` to check your repository content)
201 (verify step skipped, run `hg verify` to check your repository content)
187 $ f -s .hg/store/data/file*
202 $ f -s .hg/store/data/file*
188 .hg/store/data/file.d: size=1046
203 .hg/store/data/file.d: size=1046
189 .hg/store/data/file.i: size=1174
204 .hg/store/data/file.i: size=1174
190 $ hg tip
205 $ hg tip
191 changeset: 1:cfa8d6e60429
206 changeset: 1:cfa8d6e60429
192 tag: tip
207 tag: tip
193 user: test
208 user: test
194 date: Thu Jan 01 00:00:00 1970 +0000
209 date: Thu Jan 01 00:00:00 1970 +0000
195 summary: b
210 summary: b
196
211
197 $ hg verify -q
212 $ hg verify -q
198 $ cd ..
213 $ cd ..
199
214
215 Test a hard crash right after the index is move into place
216 ===========================================================
217
218 Now retry the procedure but intercept the rename of the index.
219
220 Things get corrupted /o\
221
222 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-crash-after-rename
223 $ cd troffset-computation-crash-after-rename
224
225 Reference size:
226 $ f -s file
227 file: size=1024
228 $ f -s .hg/store/data/file*
229 .hg/store/data/file.i: size=1174
230
231 $ cat > .hg/hgrc <<EOF
232 > [extensions]
233 > intercept_rename = $TESTTMP/intercept_after_rename.py
234 > [hooks]
235 > pretxnchangegroup = python:$TESTTMP/killme.py:killme
236 > EOF
237 #if chg
238 $ hg pull ../troffset-computation
239 pulling from ../troffset-computation
240 [255]
241 #else
242 $ hg pull ../troffset-computation
243 pulling from ../troffset-computation
244 Killed
245 [137]
246 #endif
247
248 the revlog has been split on disk
249
250 $ f -s .hg/store/data/file*
251 .hg/store/data/file.d: size=132139
252 .hg/store/data/file.i: size=256
253
254 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
255 data/file.i 1174
256 data/file.d 0
257 data/file.d 1046
258
259 $ hg recover
260 rolling back interrupted transaction
261 abort: attempted to truncate data/file.i to 1174 bytes, but it was already 256 bytes
262
263 [255]
264 $ f -s .hg/store/data/file*
265 .hg/store/data/file.d: size=1046
266 .hg/store/data/file.i: size=256
267 $ hg tip
268 changeset: 1:cfa8d6e60429
269 tag: tip
270 user: test
271 date: Thu Jan 01 00:00:00 1970 +0000
272 summary: b
273
274 $ hg verify -q
275 abandoned transaction found - run hg recover
276 warning: revlog 'data/file.d' not in fncache!
277 file@0: data length off by -131093 bytes
278 file@2: unpacking fa1120531cc1: partial read of revlog data/file.d; expected 21 bytes from offset 1046, got 0
279 file@3: unpacking a631378adaa3: partial read of revlog data/file.d; expected 131072 bytes from offset 1067, got -21
280 file@?: rev 2 points to nonexistent changeset 2
281 (expected )
282 file@?: fa1120531cc1 not in manifests
283 file@?: rev 3 points to nonexistent changeset 3
284 (expected )
285 file@?: a631378adaa3 not in manifests
286 not checking dirstate because of previous errors
287 3 warnings encountered!
288 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
289 7 integrity errors encountered!
290 (first damaged changeset appears to be 0)
291 [1]
292 $ cd ..
293
200 Have the transaction rollback itself without any hard crash
294 Have the transaction rollback itself without any hard crash
201 ===========================================================
295 ===========================================================
202
296
203
297
204 Repeat the original test but let hg rollback the transaction.
298 Repeat the original test but let hg rollback the transaction.
205
299
206 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy-rb
300 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy-rb
207 $ cd troffset-computation-copy-rb
301 $ cd troffset-computation-copy-rb
208 $ cat > .hg/hgrc <<EOF
302 $ cat > .hg/hgrc <<EOF
209 > [hooks]
303 > [hooks]
210 > pretxnchangegroup = false
304 > pretxnchangegroup = false
211 > EOF
305 > EOF
212 $ hg pull ../troffset-computation
306 $ hg pull ../troffset-computation
213 pulling from ../troffset-computation
307 pulling from ../troffset-computation
214 searching for changes
308 searching for changes
215 adding changesets
309 adding changesets
216 adding manifests
310 adding manifests
217 adding file changes
311 adding file changes
218 transaction abort!
312 transaction abort!
219 rollback completed
313 rollback completed
220 abort: pretxnchangegroup hook exited with status 1
314 abort: pretxnchangegroup hook exited with status 1
221 [40]
315 [40]
222
316
223 File are still split on disk, with the expected size.
317 File are still split on disk, with the expected size.
224
318
225 $ f -s .hg/store/data/file*
319 $ f -s .hg/store/data/file*
226 .hg/store/data/file.d: size=1046
320 .hg/store/data/file.d: size=1046
227 .hg/store/data/file.i: size=128
321 .hg/store/data/file.i: size=128
228
322
229 $ hg tip
323 $ hg tip
230 changeset: 1:cfa8d6e60429
324 changeset: 1:cfa8d6e60429
231 tag: tip
325 tag: tip
232 user: test
326 user: test
233 date: Thu Jan 01 00:00:00 1970 +0000
327 date: Thu Jan 01 00:00:00 1970 +0000
234 summary: b
328 summary: b
235
329
236 $ hg verify -q
330 $ hg verify -q
237 warning: revlog 'data/file.d' not in fncache!
331 warning: revlog 'data/file.d' not in fncache!
238 1 warnings encountered!
332 1 warnings encountered!
239 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
333 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
240 $ cd ..
334 $ cd ..
241
335
General Comments 0
You need to be logged in to leave comments. Login now