test-fncache.t
510 lines
| 14.3 KiB
| text/troff
|
Tads3Lexer
/ tests / test-fncache.t
|
r37433 | #require repofncache | ||
|
r11865 | Init repo1: | ||
$ hg init repo1 | ||||
$ cd repo1 | ||||
$ echo "some text" > a | ||||
$ hg add | ||||
adding a | ||||
$ hg ci -m first | ||||
|
r13389 | $ cat .hg/store/fncache | sort | ||
|
r11865 | data/a.i | ||
Testing a.i/b: | ||||
$ mkdir a.i | ||||
$ echo "some other text" > a.i/b | ||||
$ hg add | ||||
|
r35394 | adding a.i/b | ||
|
r11865 | $ hg ci -m second | ||
|
r13389 | $ cat .hg/store/fncache | sort | ||
|
r11865 | data/a.i | ||
data/a.i.hg/b.i | ||||
Testing a.i.hg/c: | ||||
$ mkdir a.i.hg | ||||
$ echo "yet another text" > a.i.hg/c | ||||
$ hg add | ||||
|
r35394 | adding a.i.hg/c | ||
|
r11865 | $ hg ci -m third | ||
|
r13389 | $ cat .hg/store/fncache | sort | ||
|
r11865 | data/a.i | ||
|
r13389 | data/a.i.hg.hg/c.i | ||
|
r11865 | data/a.i.hg/b.i | ||
Testing verify: | ||||
$ hg verify | ||||
checking changesets | ||||
checking manifests | ||||
crosschecking files in changesets and manifests | ||||
checking files | ||||
|
r39525 | checked 3 changesets with 3 changes to 3 files | ||
|
r11865 | |||
$ rm .hg/store/fncache | ||||
$ hg verify | ||||
checking changesets | ||||
checking manifests | ||||
crosschecking files in changesets and manifests | ||||
checking files | ||||
|
r25627 | warning: revlog 'data/a.i' not in fncache! | ||
warning: revlog 'data/a.i.hg/c.i' not in fncache! | ||||
warning: revlog 'data/a.i/b.i' not in fncache! | ||||
|
r39525 | checked 3 changesets with 3 changes to 3 files | ||
|
r25627 | 3 warnings encountered! | ||
|
r25653 | hint: run "hg debugrebuildfncache" to recover from corrupt fncache | ||
Follow the hint to make sure it works | ||||
$ hg debugrebuildfncache | ||||
adding data/a.i | ||||
adding data/a.i.hg/c.i | ||||
adding data/a.i/b.i | ||||
3 items added, 0 removed from fncache | ||||
$ hg verify | ||||
checking changesets | ||||
checking manifests | ||||
crosschecking files in changesets and manifests | ||||
checking files | ||||
|
r39525 | checked 3 changesets with 3 changes to 3 files | ||
|
r25653 | |||
|
r11865 | $ cd .. | ||
Non store repo: | ||||
$ hg --config format.usestore=False init foo | ||||
$ cd foo | ||||
$ mkdir tst.d | ||||
$ echo foo > tst.d/foo | ||||
$ hg ci -Amfoo | ||||
adding tst.d/foo | ||||
$ find .hg | sort | ||||
.hg | ||||
.hg/00changelog.i | ||||
.hg/00manifest.i | ||||
|
r15886 | .hg/cache | ||
|
r20185 | .hg/cache/branch2-served | ||
|
r39359 | .hg/cache/manifestfulltextcache (reporevlogstore !) | ||
|
r23786 | .hg/cache/rbc-names-v1 | ||
.hg/cache/rbc-revs-v1 | ||||
|
r11865 | .hg/data | ||
.hg/data/tst.d.hg | ||||
.hg/data/tst.d.hg/foo.i | ||||
.hg/dirstate | ||||
|
r33427 | .hg/fsmonitor.state (fsmonitor !) | ||
|
r11865 | .hg/last-message.txt | ||
|
r15483 | .hg/phaseroots | ||
|
r11865 | .hg/requires | ||
.hg/undo | ||||
|
r26998 | .hg/undo.backup.dirstate | ||
|
r23904 | .hg/undo.backupfiles | ||
|
r14266 | .hg/undo.bookmarks | ||
|
r11865 | .hg/undo.branch | ||
.hg/undo.desc | ||||
.hg/undo.dirstate | ||||
|
r15455 | .hg/undo.phaseroots | ||
|
r11865 | $ cd .. | ||
Non fncache repo: | ||||
$ hg --config format.usefncache=False init bar | ||||
$ cd bar | ||||
$ mkdir tst.d | ||||
$ echo foo > tst.d/Foo | ||||
$ hg ci -Amfoo | ||||
adding tst.d/Foo | ||||
$ find .hg | sort | ||||
.hg | ||||
.hg/00changelog.i | ||||
|
r15886 | .hg/cache | ||
|
r20185 | .hg/cache/branch2-served | ||
|
r39359 | .hg/cache/manifestfulltextcache (reporevlogstore !) | ||
|
r23786 | .hg/cache/rbc-names-v1 | ||
.hg/cache/rbc-revs-v1 | ||||
|
r11865 | .hg/dirstate | ||
|
r33427 | .hg/fsmonitor.state (fsmonitor !) | ||
|
r11865 | .hg/last-message.txt | ||
.hg/requires | ||||
.hg/store | ||||
.hg/store/00changelog.i | ||||
.hg/store/00manifest.i | ||||
.hg/store/data | ||||
.hg/store/data/tst.d.hg | ||||
.hg/store/data/tst.d.hg/_foo.i | ||||
|
r15483 | .hg/store/phaseroots | ||
|
r11865 | .hg/store/undo | ||
|
r23904 | .hg/store/undo.backupfiles | ||
|
r15455 | .hg/store/undo.phaseroots | ||
|
r26998 | .hg/undo.backup.dirstate | ||
|
r14266 | .hg/undo.bookmarks | ||
|
r11865 | .hg/undo.branch | ||
.hg/undo.desc | ||||
.hg/undo.dirstate | ||||
$ cd .. | ||||
|
r17710 | Encoding of reserved / long paths in the store | ||
$ hg init r2 | ||||
$ cd r2 | ||||
$ cat <<EOF > .hg/hgrc | ||||
> [ui] | ||||
> portablefilenames = ignore | ||||
> EOF | ||||
|
r17748 | $ hg import -q --bypass - <<EOF | ||
> # HG changeset patch | ||||
> # User test | ||||
> # Date 0 0 | ||||
> # Node ID 1c7a2f7cb77be1a0def34e4c7cabc562ad98fbd7 | ||||
> # Parent 0000000000000000000000000000000000000000 | ||||
> 1 | ||||
> | ||||
> 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 | ||||
> new file mode 100644 | ||||
> --- /dev/null | ||||
> +++ b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz | ||||
> @@ -0,0 +1,1 @@ | ||||
> +foo | ||||
> 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 | ||||
> new file mode 100644 | ||||
> --- /dev/null | ||||
> +++ b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT | ||||
> @@ -0,0 +1,1 @@ | ||||
> +foo | ||||
> diff --git a/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt | ||||
> new file mode 100644 | ||||
> --- /dev/null | ||||
> +++ b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt | ||||
> @@ -0,0 +1,1 @@ | ||||
> +foo | ||||
> 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 | ||||
> new file mode 100644 | ||||
> --- /dev/null | ||||
> +++ b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c | ||||
> @@ -0,0 +1,1 @@ | ||||
> +foo | ||||
> 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 | ||||
> new file mode 100644 | ||||
> --- /dev/null | ||||
> +++ b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider | ||||
> @@ -0,0 +1,1 @@ | ||||
> +foo | ||||
> EOF | ||||
|
r17710 | $ find .hg/store -name *.i | sort | ||
.hg/store/00changelog.i | ||||
.hg/store/00manifest.i | ||||
.hg/store/data/bla.aux/pr~6e/_p_r_n/lpt/co~6d3/nu~6c/coma/foo._n_u_l/normal.c.i | ||||
.hg/store/dh/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxx168e07b38e65eff86ab579afaaa8e30bfbe0f35f.i | ||||
.hg/store/dh/au~78/second/x.prn/fourth/fi~3afth/sixth/seventh/eighth/nineth/tenth/loremia20419e358ddff1bf8751e38288aff1d7c32ec05.i | ||||
.hg/store/dh/enterpri/openesba/contrib-/corba-bc/netbeans/wsdlexte/src/main/java/org.net7018f27961fdf338a598a40c4683429e7ffb9743.i | ||||
.hg/store/dh/project_/resource/anotherl/followed/andanoth/andthenanextremelylongfilename0d8e1f4187c650e2f1fdca9fd90f786bc0976b6b.i | ||||
$ cd .. | ||||
|
r20883 | Aborting lock does not prevent fncache writes | ||
|
r17710 | |||
|
r20883 | $ cat > exceptionext.py <<EOF | ||
|
r33958 | > from __future__ import absolute_import | ||
|
r20883 | > import os | ||
|
r33958 | > from mercurial import commands, error, extensions | ||
|
r20883 | > | ||
|
r26497 | > def lockexception(orig, vfs, lockname, wait, releasefn, *args, **kwargs): | ||
|
r20883 | > def releasewrap(): | ||
|
r27168 | > l.held = False # ensure __del__ is a noop | ||
|
r26587 | > raise error.Abort("forced lock failure") | ||
|
r27168 | > l = orig(vfs, lockname, wait, releasewrap, *args, **kwargs) | ||
> return l | ||||
|
r20883 | > | ||
> def reposetup(ui, repo): | ||||
|
r33958 | > extensions.wrapfunction(repo, '_lock', lockexception) | ||
|
r20883 | > | ||
> cmdtable = {} | ||||
> | ||||
|
r27192 | > # wrap "commit" command to prevent wlock from being '__del__()'-ed | ||
> # at the end of dispatching (for intentional "forced lcok failure") | ||||
> def commitwrap(orig, ui, repo, *pats, **opts): | ||||
> repo = repo.unfiltered() # to use replaced repo._lock certainly | ||||
> wlock = repo.wlock() | ||||
> try: | ||||
> return orig(ui, repo, *pats, **opts) | ||||
> finally: | ||||
> # multiple 'relase()' is needed for complete releasing wlock, | ||||
> # because "forced" abort at last releasing store lock | ||||
> # prevents wlock from being released at same 'lockmod.release()' | ||||
> for i in range(wlock.held): | ||||
> wlock.release() | ||||
> | ||||
> def extsetup(ui): | ||||
|
r36511 | > extensions.wrapcommand(commands.table, b"commit", commitwrap) | ||
|
r20883 | > EOF | ||
$ extpath=`pwd`/exceptionext.py | ||||
$ hg init fncachetxn | ||||
$ cd fncachetxn | ||||
$ printf "[extensions]\nexceptionext=$extpath\n" >> .hg/hgrc | ||||
$ touch y | ||||
$ hg ci -qAm y | ||||
abort: forced lock failure | ||||
[255] | ||||
$ cat .hg/store/fncache | ||||
data/y.i | ||||
Aborting transaction prevents fncache change | ||||
$ cat > ../exceptionext.py <<EOF | ||||
|
r33958 | > from __future__ import absolute_import | ||
|
r20883 | > import os | ||
|
r33958 | > from mercurial import commands, error, extensions, localrepo | ||
|
r20883 | > | ||
> def wrapper(orig, self, *args, **kwargs): | ||||
|
r23510 | > tr = orig(self, *args, **kwargs) | ||
> def fail(tr): | ||||
|
r36680 | > raise error.Abort(b"forced transaction failure") | ||
|
r23510 | > # zzz prefix to ensure it sorted after store.write | ||
|
r36680 | > tr.addfinalize(b'zzz-forcefails', fail) | ||
|
r23510 | > return tr | ||
|
r20883 | > | ||
> def uisetup(ui): | ||||
|
r33958 | > extensions.wrapfunction( | ||
|
r36680 | > localrepo.localrepository, b'transaction', wrapper) | ||
|
r20883 | > | ||
> cmdtable = {} | ||||
> | ||||
> EOF | ||||
|
r33609 | |||
Clean cached version | ||||
|
r21760 | $ rm -f "${extpath}c" | ||
|
r33609 | $ rm -Rf "`dirname $extpath`/__pycache__" | ||
|
r20883 | $ touch z | ||
$ hg ci -qAm z | ||||
transaction abort! | ||||
rollback completed | ||||
abort: forced transaction failure | ||||
[255] | ||||
$ cat .hg/store/fncache | ||||
data/y.i | ||||
|
r23063 | |||
Aborted transactions can be recovered later | ||||
$ cat > ../exceptionext.py <<EOF | ||||
|
r33958 | > from __future__ import absolute_import | ||
|
r23063 | > import os | ||
|
r33958 | > from mercurial import ( | ||
> commands, | ||||
> error, | ||||
> extensions, | ||||
> localrepo, | ||||
> transaction, | ||||
> ) | ||||
|
r23063 | > | ||
|
r23512 | > def trwrapper(orig, self, *args, **kwargs): | ||
> tr = orig(self, *args, **kwargs) | ||||
> def fail(tr): | ||||
|
r26587 | > raise error.Abort("forced transaction failure") | ||
|
r23512 | > # zzz prefix to ensure it sorted after store.write | ||
> tr.addfinalize('zzz-forcefails', fail) | ||||
> return tr | ||||
|
r23063 | > | ||
> def abortwrapper(orig, self, *args, **kwargs): | ||||
|
r26587 | > raise error.Abort("forced transaction failure") | ||
|
r23063 | > | ||
> def uisetup(ui): | ||||
|
r33958 | > extensions.wrapfunction(localrepo.localrepository, 'transaction', | ||
> trwrapper) | ||||
> extensions.wrapfunction(transaction.transaction, '_abort', | ||||
> abortwrapper) | ||||
|
r23063 | > | ||
> cmdtable = {} | ||||
> | ||||
> EOF | ||||
|
r33609 | |||
Clean cached versions | ||||
|
r23063 | $ rm -f "${extpath}c" | ||
|
r33609 | $ rm -Rf "`dirname $extpath`/__pycache__" | ||
|
r23063 | $ hg up -q 1 | ||
$ touch z | ||||
$ hg ci -qAm z 2>/dev/null | ||||
[255] | ||||
$ cat .hg/store/fncache | sort | ||||
data/y.i | ||||
data/z.i | ||||
$ hg recover | ||||
rolling back interrupted transaction | ||||
checking changesets | ||||
checking manifests | ||||
crosschecking files in changesets and manifests | ||||
checking files | ||||
|
r39525 | checked 1 changesets with 1 changes to 1 files | ||
|
r23063 | $ cat .hg/store/fncache | ||
data/y.i | ||||
|
r25652 | |||
$ cd .. | ||||
debugrebuildfncache does nothing unless repo has fncache requirement | ||||
$ hg --config format.usefncache=false init nofncache | ||||
$ cd nofncache | ||||
$ hg debugrebuildfncache | ||||
|
r25874 | (not rebuilding fncache because repository does not support fncache) | ||
|
r25652 | |||
$ cd .. | ||||
debugrebuildfncache works on empty repository | ||||
$ hg init empty | ||||
$ cd empty | ||||
$ hg debugrebuildfncache | ||||
fncache already up to date | ||||
$ cd .. | ||||
debugrebuildfncache on an up to date repository no-ops | ||||
$ hg init repo | ||||
$ cd repo | ||||
$ echo initial > foo | ||||
$ echo initial > .bar | ||||
$ hg commit -A -m initial | ||||
adding .bar | ||||
adding foo | ||||
$ cat .hg/store/fncache | sort | ||||
data/.bar.i | ||||
data/foo.i | ||||
$ hg debugrebuildfncache | ||||
fncache already up to date | ||||
debugrebuildfncache restores deleted fncache file | ||||
$ rm -f .hg/store/fncache | ||||
$ hg debugrebuildfncache | ||||
adding data/.bar.i | ||||
adding data/foo.i | ||||
2 items added, 0 removed from fncache | ||||
$ cat .hg/store/fncache | sort | ||||
data/.bar.i | ||||
data/foo.i | ||||
Rebuild after rebuild should no-op | ||||
$ hg debugrebuildfncache | ||||
fncache already up to date | ||||
A single missing file should get restored, an extra file should be removed | ||||
$ cat > .hg/store/fncache << EOF | ||||
> data/foo.i | ||||
> data/bad-entry.i | ||||
> EOF | ||||
$ hg debugrebuildfncache | ||||
removing data/bad-entry.i | ||||
adding data/.bar.i | ||||
1 items added, 1 removed from fncache | ||||
$ cat .hg/store/fncache | sort | ||||
data/.bar.i | ||||
data/foo.i | ||||
$ cd .. | ||||
Try a simple variation without dotencode to ensure fncache is ignorant of encoding | ||||
$ hg --config format.dotencode=false init nodotencode | ||||
$ cd nodotencode | ||||
$ echo initial > foo | ||||
$ echo initial > .bar | ||||
$ hg commit -A -m initial | ||||
adding .bar | ||||
adding foo | ||||
$ cat .hg/store/fncache | sort | ||||
data/.bar.i | ||||
data/foo.i | ||||
$ rm .hg/store/fncache | ||||
$ hg debugrebuildfncache | ||||
adding data/.bar.i | ||||
adding data/foo.i | ||||
2 items added, 0 removed from fncache | ||||
$ cat .hg/store/fncache | sort | ||||
data/.bar.i | ||||
data/foo.i | ||||
|
r38683 | |||
$ cd .. | ||||
In repositories that have accumulated a large number of files over time, the | ||||
fncache file is going to be large. If we possibly can avoid loading it, so much the better. | ||||
The cache should not loaded when committing changes to existing files, or when unbundling | ||||
changesets that only contain changes to existing files: | ||||
$ cat > fncacheloadwarn.py << EOF | ||||
> from __future__ import absolute_import | ||||
> from mercurial import extensions, store | ||||
> | ||||
> def extsetup(ui): | ||||
> def wrapstore(orig, requirements, *args): | ||||
> store = orig(requirements, *args) | ||||
> if 'store' in requirements and 'fncache' in requirements: | ||||
> instrumentfncachestore(store, ui) | ||||
> return store | ||||
> extensions.wrapfunction(store, 'store', wrapstore) | ||||
> | ||||
> def instrumentfncachestore(fncachestore, ui): | ||||
> class instrumentedfncache(type(fncachestore.fncache)): | ||||
> def _load(self): | ||||
> ui.warn('fncache load triggered!\n') | ||||
> super(instrumentedfncache, self)._load() | ||||
> fncachestore.fncache.__class__ = instrumentedfncache | ||||
> EOF | ||||
$ fncachextpath=`pwd`/fncacheloadwarn.py | ||||
$ hg init nofncacheload | ||||
$ cd nofncacheload | ||||
$ printf "[extensions]\nfncacheloadwarn=$fncachextpath\n" >> .hg/hgrc | ||||
A new file should trigger a load, as we'd want to update the fncache set in that case: | ||||
$ touch foo | ||||
$ hg ci -qAm foo | ||||
fncache load triggered! | ||||
But modifying that file should not: | ||||
$ echo bar >> foo | ||||
$ hg ci -qm foo | ||||
If a transaction has been aborted, the zero-size truncated index file will | ||||
not prevent the fncache from being loaded; rather than actually abort | ||||
a transaction, we simulate the situation by creating a zero-size index file: | ||||
$ touch .hg/store/data/bar.i | ||||
$ touch bar | ||||
$ hg ci -qAm bar | ||||
fncache load triggered! | ||||
Unbundling should follow the same rules; existing files should not cause a load: | ||||
$ hg clone -q . tobundle | ||||
$ echo 'new line' > tobundle/bar | ||||
$ hg -R tobundle ci -qm bar | ||||
$ hg -R tobundle bundle -q barupdated.hg | ||||
$ hg unbundle -q barupdated.hg | ||||
but adding new files should: | ||||
$ touch tobundle/newfile | ||||
$ hg -R tobundle ci -qAm newfile | ||||
$ hg -R tobundle bundle -q newfile.hg | ||||
$ hg unbundle -q newfile.hg | ||||
fncache load triggered! | ||||
$ cd .. | ||||