##// END OF EJS Templates
test: use a more direct form of interruption in fncache "recover" testing...
marmoute -
r50887:420fad6b default
parent child Browse files
Show More
@@ -1,537 +1,537 b''
1 1 #require repofncache
2 2
3 3 An extension which will set fncache chunksize to 1 byte to make sure that logic
4 4 does not break
5 5
6 6 $ cat > chunksize.py <<EOF
7 7 > from mercurial import store
8 8 > store.fncache_chunksize = 1
9 9 > EOF
10 10
11 11 $ cat >> $HGRCPATH <<EOF
12 12 > [extensions]
13 13 > chunksize = $TESTTMP/chunksize.py
14 14 > EOF
15 15
16 16 Init repo1:
17 17
18 18 $ hg init repo1
19 19 $ cd repo1
20 20 $ echo "some text" > a
21 21 $ hg add
22 22 adding a
23 23 $ hg ci -m first
24 24 $ cat .hg/store/fncache | sort
25 25 data/a.i
26 26
27 27 Testing a.i/b:
28 28
29 29 $ mkdir a.i
30 30 $ echo "some other text" > a.i/b
31 31 $ hg add
32 32 adding a.i/b
33 33 $ hg ci -m second
34 34 $ cat .hg/store/fncache | sort
35 35 data/a.i
36 36 data/a.i.hg/b.i
37 37
38 38 Testing a.i.hg/c:
39 39
40 40 $ mkdir a.i.hg
41 41 $ echo "yet another text" > a.i.hg/c
42 42 $ hg add
43 43 adding a.i.hg/c
44 44 $ hg ci -m third
45 45 $ cat .hg/store/fncache | sort
46 46 data/a.i
47 47 data/a.i.hg.hg/c.i
48 48 data/a.i.hg/b.i
49 49
50 50 Testing verify:
51 51
52 52 $ hg verify -q
53 53
54 54 $ rm .hg/store/fncache
55 55
56 56 $ hg verify
57 57 checking changesets
58 58 checking manifests
59 59 crosschecking files in changesets and manifests
60 60 checking files
61 61 warning: revlog 'data/a.i' not in fncache!
62 62 warning: revlog 'data/a.i.hg/c.i' not in fncache!
63 63 warning: revlog 'data/a.i/b.i' not in fncache!
64 64 checking dirstate
65 65 checked 3 changesets with 3 changes to 3 files
66 66 3 warnings encountered!
67 67 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
68 68
69 69 Follow the hint to make sure it works
70 70
71 71 $ hg debugrebuildfncache
72 72 adding data/a.i
73 73 adding data/a.i.hg/c.i
74 74 adding data/a.i/b.i
75 75 3 items added, 0 removed from fncache
76 76
77 77 $ hg verify -q
78 78
79 79 $ cd ..
80 80
81 81 Non store repo:
82 82
83 83 $ hg --config format.usestore=False init foo
84 84 $ cd foo
85 85 $ mkdir tst.d
86 86 $ echo foo > tst.d/foo
87 87 $ hg ci -Amfoo
88 88 adding tst.d/foo
89 89 $ find .hg | sort
90 90 .hg
91 91 .hg/00changelog.i
92 92 .hg/00manifest.i
93 93 .hg/cache
94 94 .hg/cache/branch2-served
95 95 .hg/cache/rbc-names-v1
96 96 .hg/cache/rbc-revs-v1
97 97 .hg/data
98 98 .hg/data/tst.d.hg
99 99 .hg/data/tst.d.hg/foo.i
100 100 .hg/dirstate
101 101 .hg/fsmonitor.state (fsmonitor !)
102 102 .hg/last-message.txt
103 103 .hg/phaseroots
104 104 .hg/requires
105 105 .hg/undo
106 106 .hg/undo.backup.dirstate
107 107 .hg/undo.backupfiles
108 108 .hg/undo.bookmarks
109 109 .hg/undo.branch
110 110 .hg/undo.desc
111 111 .hg/undo.dirstate
112 112 .hg/undo.phaseroots
113 113 .hg/wcache
114 114 .hg/wcache/checkisexec (execbit !)
115 115 .hg/wcache/checklink (symlink !)
116 116 .hg/wcache/checklink-target (symlink !)
117 117 .hg/wcache/manifestfulltextcache (reporevlogstore !)
118 118 $ cd ..
119 119
120 120 Non fncache repo:
121 121
122 122 $ hg --config format.usefncache=False init bar
123 123 $ cd bar
124 124 $ mkdir tst.d
125 125 $ echo foo > tst.d/Foo
126 126 $ hg ci -Amfoo
127 127 adding tst.d/Foo
128 128 $ find .hg | sort
129 129 .hg
130 130 .hg/00changelog.i
131 131 .hg/cache
132 132 .hg/cache/branch2-served
133 133 .hg/cache/rbc-names-v1
134 134 .hg/cache/rbc-revs-v1
135 135 .hg/dirstate
136 136 .hg/fsmonitor.state (fsmonitor !)
137 137 .hg/last-message.txt
138 138 .hg/requires
139 139 .hg/store
140 140 .hg/store/00changelog.i
141 141 .hg/store/00manifest.i
142 142 .hg/store/data
143 143 .hg/store/data/tst.d.hg
144 144 .hg/store/data/tst.d.hg/_foo.i
145 145 .hg/store/phaseroots
146 146 .hg/store/requires
147 147 .hg/store/undo
148 148 .hg/store/undo.backupfiles
149 149 .hg/store/undo.phaseroots
150 150 .hg/undo.backup.dirstate
151 151 .hg/undo.bookmarks
152 152 .hg/undo.branch
153 153 .hg/undo.desc
154 154 .hg/undo.dirstate
155 155 .hg/wcache
156 156 .hg/wcache/checkisexec (execbit !)
157 157 .hg/wcache/checklink (symlink !)
158 158 .hg/wcache/checklink-target (symlink !)
159 159 .hg/wcache/manifestfulltextcache (reporevlogstore !)
160 160 $ cd ..
161 161
162 162 Encoding of reserved / long paths in the store
163 163
164 164 $ hg init r2
165 165 $ cd r2
166 166 $ cat <<EOF > .hg/hgrc
167 167 > [ui]
168 168 > portablefilenames = ignore
169 169 > EOF
170 170
171 171 $ hg import -q --bypass - <<EOF
172 172 > # HG changeset patch
173 173 > # User test
174 174 > # Date 0 0
175 175 > # Node ID 1c7a2f7cb77be1a0def34e4c7cabc562ad98fbd7
176 176 > # Parent 0000000000000000000000000000000000000000
177 177 > 1
178 178 >
179 179 > diff --git a/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
180 180 > new file mode 100644
181 181 > --- /dev/null
182 182 > +++ b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
183 183 > @@ -0,0 +1,1 @@
184 184 > +foo
185 185 > diff --git a/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
186 186 > new file mode 100644
187 187 > --- /dev/null
188 188 > +++ b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
189 189 > @@ -0,0 +1,1 @@
190 190 > +foo
191 191 > diff --git a/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
192 192 > new file mode 100644
193 193 > --- /dev/null
194 194 > +++ b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
195 195 > @@ -0,0 +1,1 @@
196 196 > +foo
197 197 > diff --git a/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
198 198 > new file mode 100644
199 199 > --- /dev/null
200 200 > +++ b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
201 201 > @@ -0,0 +1,1 @@
202 202 > +foo
203 203 > diff --git a/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
204 204 > new file mode 100644
205 205 > --- /dev/null
206 206 > +++ b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
207 207 > @@ -0,0 +1,1 @@
208 208 > +foo
209 209 > EOF
210 210
211 211 $ find .hg/store -name *.i | sort
212 212 .hg/store/00changelog.i
213 213 .hg/store/00manifest.i
214 214 .hg/store/data/bla.aux/pr~6e/_p_r_n/lpt/co~6d3/nu~6c/coma/foo._n_u_l/normal.c.i
215 215 .hg/store/dh/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxx168e07b38e65eff86ab579afaaa8e30bfbe0f35f.i
216 216 .hg/store/dh/au~78/second/x.prn/fourth/fi~3afth/sixth/seventh/eighth/nineth/tenth/loremia20419e358ddff1bf8751e38288aff1d7c32ec05.i
217 217 .hg/store/dh/enterpri/openesba/contrib-/corba-bc/netbeans/wsdlexte/src/main/java/org.net7018f27961fdf338a598a40c4683429e7ffb9743.i
218 218 .hg/store/dh/project_/resource/anotherl/followed/andanoth/andthenanextremelylongfilename0d8e1f4187c650e2f1fdca9fd90f786bc0976b6b.i
219 219
220 220 $ cd ..
221 221
222 222 Aborting lock does not prevent fncache writes
223 223
224 224 $ cat > exceptionext.py <<EOF
225 225 > import os
226 226 > from mercurial import commands, error, extensions
227 227 >
228 228 > def lockexception(orig, vfs, lockname, wait, releasefn, *args, **kwargs):
229 229 > def releasewrap():
230 230 > l.held = False # ensure __del__ is a noop
231 231 > raise error.Abort(b"forced lock failure")
232 232 > l = orig(vfs, lockname, wait, releasewrap, *args, **kwargs)
233 233 > return l
234 234 >
235 235 > def reposetup(ui, repo):
236 236 > extensions.wrapfunction(repo, '_lock', lockexception)
237 237 >
238 238 > cmdtable = {}
239 239 >
240 240 > # wrap "commit" command to prevent wlock from being '__del__()'-ed
241 241 > # at the end of dispatching (for intentional "forced lcok failure")
242 242 > def commitwrap(orig, ui, repo, *pats, **opts):
243 243 > repo = repo.unfiltered() # to use replaced repo._lock certainly
244 244 > wlock = repo.wlock()
245 245 > try:
246 246 > return orig(ui, repo, *pats, **opts)
247 247 > finally:
248 248 > # multiple 'relase()' is needed for complete releasing wlock,
249 249 > # because "forced" abort at last releasing store lock
250 250 > # prevents wlock from being released at same 'lockmod.release()'
251 251 > for i in range(wlock.held):
252 252 > wlock.release()
253 253 >
254 254 > def extsetup(ui):
255 255 > extensions.wrapcommand(commands.table, b"commit", commitwrap)
256 256 > EOF
257 257 $ extpath=`pwd`/exceptionext.py
258 258 $ hg init fncachetxn
259 259 $ cd fncachetxn
260 260 $ printf "[extensions]\nexceptionext=$extpath\n" >> .hg/hgrc
261 261 $ touch y
262 262 $ hg ci -qAm y
263 263 abort: forced lock failure
264 264 [255]
265 265 $ cat .hg/store/fncache
266 266 data/y.i
267 267
268 268 Aborting transaction prevents fncache change
269 269
270 270 $ cat > ../exceptionext.py <<EOF
271 271 > import os
272 272 > from mercurial import commands, error, extensions, localrepo
273 273 >
274 274 > def wrapper(orig, self, *args, **kwargs):
275 275 > tr = orig(self, *args, **kwargs)
276 276 > def fail(tr):
277 277 > raise error.Abort(b"forced transaction failure")
278 278 > # zzz prefix to ensure it sorted after store.write
279 279 > tr.addfinalize(b'zzz-forcefails', fail)
280 280 > return tr
281 281 >
282 282 > def uisetup(ui):
283 283 > extensions.wrapfunction(
284 284 > localrepo.localrepository, b'transaction', wrapper)
285 285 >
286 286 > cmdtable = {}
287 287 >
288 288 > EOF
289 289
290 290 Clean cached version
291 291 $ rm -f "${extpath}c"
292 292 $ rm -Rf "`dirname $extpath`/__pycache__"
293 293
294 294 $ touch z
295 295 $ hg ci -qAm z
296 296 transaction abort!
297 297 rollback completed
298 298 abort: forced transaction failure
299 299 [255]
300 300 $ cat .hg/store/fncache
301 301 data/y.i
302 302
303 303 Aborted transactions can be recovered later
304 304
305 305 $ cat > ../exceptionext.py <<EOF
306 306 > import os
307 > import signal
307 308 > from mercurial import (
308 309 > commands,
309 310 > error,
310 311 > extensions,
311 312 > localrepo,
312 313 > transaction,
313 314 > )
314 315 >
315 316 > def trwrapper(orig, self, *args, **kwargs):
316 317 > tr = orig(self, *args, **kwargs)
317 318 > def fail(tr):
318 > raise error.Abort(b"forced transaction failure")
319 > os.kill(os.getpid(), signal.SIGKILL)
319 320 > # zzz prefix to ensure it sorted after store.write
320 321 > tr.addfinalize(b'zzz-forcefails', fail)
321 322 > return tr
322 323 >
323 > def abortwrapper(orig, self, *args, **kwargs):
324 > raise error.Abort(b"forced transaction failure")
325 >
326 324 > def uisetup(ui):
327 325 > extensions.wrapfunction(localrepo.localrepository, 'transaction',
328 326 > trwrapper)
329 > extensions.wrapfunction(transaction.transaction, '_abort',
330 > abortwrapper)
331 327 >
332 328 > cmdtable = {}
333 329 >
334 330 > EOF
335 331
336 332 Clean cached versions
337 333 $ rm -f "${extpath}c"
338 334 $ rm -Rf "`dirname $extpath`/__pycache__"
339 335
340 336 $ hg up -q 1
341 337 $ touch z
342 $ hg ci -qAm z 2>/dev/null
343 [255]
338 # Cannot rely on the return code value as chg use a different one.
339 # So we use a `|| echo` trick
340 # XXX-CHG fixing chg behavior would be nice here.
341 $ hg ci -qAm z || echo "He's Dead, Jim." 2>/dev/null
342 Killed (?)
343 He's Dead, Jim.
344 344 $ cat .hg/store/fncache | sort
345 345 data/y.i
346 346 data/z.i
347 347 $ hg recover --verify
348 348 rolling back interrupted transaction
349 349 checking changesets
350 350 checking manifests
351 351 crosschecking files in changesets and manifests
352 352 checking files
353 353 checking dirstate
354 354 checked 1 changesets with 1 changes to 1 files
355 355 $ cat .hg/store/fncache
356 356 data/y.i
357 357
358 358 $ cd ..
359 359
360 360 debugrebuildfncache does nothing unless repo has fncache requirement
361 361
362 362 $ hg --config format.usefncache=false init nofncache
363 363 $ cd nofncache
364 364 $ hg debugrebuildfncache
365 365 (not rebuilding fncache because repository does not support fncache)
366 366
367 367 $ cd ..
368 368
369 369 debugrebuildfncache works on empty repository
370 370
371 371 $ hg init empty
372 372 $ cd empty
373 373 $ hg debugrebuildfncache
374 374 fncache already up to date
375 375 $ cd ..
376 376
377 377 debugrebuildfncache on an up to date repository no-ops
378 378
379 379 $ hg init repo
380 380 $ cd repo
381 381 $ echo initial > foo
382 382 $ echo initial > .bar
383 383 $ hg commit -A -m initial
384 384 adding .bar
385 385 adding foo
386 386
387 387 $ cat .hg/store/fncache | sort
388 388 data/.bar.i
389 389 data/foo.i
390 390
391 391 $ hg debugrebuildfncache
392 392 fncache already up to date
393 393
394 394 debugrebuildfncache restores deleted fncache file
395 395
396 396 $ rm -f .hg/store/fncache
397 397 $ hg debugrebuildfncache
398 398 adding data/.bar.i
399 399 adding data/foo.i
400 400 2 items added, 0 removed from fncache
401 401
402 402 $ cat .hg/store/fncache | sort
403 403 data/.bar.i
404 404 data/foo.i
405 405
406 406 Rebuild after rebuild should no-op
407 407
408 408 $ hg debugrebuildfncache
409 409 fncache already up to date
410 410
411 411 A single missing file should get restored, an extra file should be removed
412 412
413 413 $ cat > .hg/store/fncache << EOF
414 414 > data/foo.i
415 415 > data/bad-entry.i
416 416 > EOF
417 417
418 418 $ hg debugrebuildfncache
419 419 removing data/bad-entry.i
420 420 adding data/.bar.i
421 421 1 items added, 1 removed from fncache
422 422
423 423 $ cat .hg/store/fncache | sort
424 424 data/.bar.i
425 425 data/foo.i
426 426
427 427 debugrebuildfncache recovers from truncated line in fncache
428 428
429 429 $ printf a > .hg/store/fncache
430 430 $ hg debugrebuildfncache
431 431 fncache does not ends with a newline
432 432 adding data/.bar.i
433 433 adding data/foo.i
434 434 2 items added, 0 removed from fncache
435 435
436 436 $ cat .hg/store/fncache | sort
437 437 data/.bar.i
438 438 data/foo.i
439 439
440 440 $ cd ..
441 441
442 442 Try a simple variation without dotencode to ensure fncache is ignorant of encoding
443 443
444 444 $ hg --config format.dotencode=false init nodotencode
445 445 $ cd nodotencode
446 446 $ echo initial > foo
447 447 $ echo initial > .bar
448 448 $ hg commit -A -m initial
449 449 adding .bar
450 450 adding foo
451 451
452 452 $ cat .hg/store/fncache | sort
453 453 data/.bar.i
454 454 data/foo.i
455 455
456 456 $ rm .hg/store/fncache
457 457 $ hg debugrebuildfncache
458 458 adding data/.bar.i
459 459 adding data/foo.i
460 460 2 items added, 0 removed from fncache
461 461
462 462 $ cat .hg/store/fncache | sort
463 463 data/.bar.i
464 464 data/foo.i
465 465
466 466 $ cd ..
467 467
468 468 In repositories that have accumulated a large number of files over time, the
469 469 fncache file is going to be large. If we possibly can avoid loading it, so much the better.
470 470 The cache should not loaded when committing changes to existing files, or when unbundling
471 471 changesets that only contain changes to existing files:
472 472
473 473 $ cat > fncacheloadwarn.py << EOF
474 474 > from mercurial import extensions, localrepo
475 475 >
476 476 > def extsetup(ui):
477 477 > def wrapstore(orig, requirements, *args):
478 478 > store = orig(requirements, *args)
479 479 > if b'store' in requirements and b'fncache' in requirements:
480 480 > instrumentfncachestore(store, ui)
481 481 > return store
482 482 > extensions.wrapfunction(localrepo, 'makestore', wrapstore)
483 483 >
484 484 > def instrumentfncachestore(fncachestore, ui):
485 485 > class instrumentedfncache(type(fncachestore.fncache)):
486 486 > def _load(self):
487 487 > ui.warn(b'fncache load triggered!\n')
488 488 > super(instrumentedfncache, self)._load()
489 489 > fncachestore.fncache.__class__ = instrumentedfncache
490 490 > EOF
491 491
492 492 $ fncachextpath=`pwd`/fncacheloadwarn.py
493 493 $ hg init nofncacheload
494 494 $ cd nofncacheload
495 495 $ printf "[extensions]\nfncacheloadwarn=$fncachextpath\n" >> .hg/hgrc
496 496
497 497 A new file should trigger a load, as we'd want to update the fncache set in that case:
498 498
499 499 $ touch foo
500 500 $ hg ci -qAm foo
501 501 fncache load triggered!
502 502
503 503 But modifying that file should not:
504 504
505 505 $ echo bar >> foo
506 506 $ hg ci -qm foo
507 507
508 508 If a transaction has been aborted, the zero-size truncated index file will
509 509 not prevent the fncache from being loaded; rather than actually abort
510 510 a transaction, we simulate the situation by creating a zero-size index file:
511 511
512 512 $ touch .hg/store/data/bar.i
513 513 $ touch bar
514 514 $ hg ci -qAm bar
515 515 fncache load triggered!
516 516
517 517 Unbundling should follow the same rules; existing files should not cause a load:
518 518
519 519 (loading during the clone is expected)
520 520 $ hg clone -q . tobundle
521 521 fncache load triggered!
522 522 fncache load triggered!
523 523
524 524 $ echo 'new line' > tobundle/bar
525 525 $ hg -R tobundle ci -qm bar
526 526 $ hg -R tobundle bundle -q barupdated.hg
527 527 $ hg unbundle -q barupdated.hg
528 528
529 529 but adding new files should:
530 530
531 531 $ touch tobundle/newfile
532 532 $ hg -R tobundle ci -qAm newfile
533 533 $ hg -R tobundle bundle -q newfile.hg
534 534 $ hg unbundle -q newfile.hg
535 535 fncache load triggered!
536 536
537 537 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now