Mercurial > hg
view tests/test-push-http.t @ 43198:c16fe77e340a
pathcopies: give up any optimization based on `introrev`
Between 8a0136f69027 and d98fb3f42f33, we sped up the search for the
introduction revision during path copies. However, further checking show that
finding the introduction revision is still expensive and that we are better off
without it. So we simply drop it and only rely on the linkrev optimisation.
I ran `perfpathcopies` on 6989 pair of revision in the pypy
repository (`hg perfhelper-pathcopies`. The result is massively in favor of
dropping this condition. The result of the copy tracing are unchanged.
Attempt to use a smaller changes preserving linkrev usage were unsuccessful, it
can return wrong result. The following changesets broke test-mv-cp-st-diff.t
- if not f.isintroducedafter(limit):
+ if limit >= 0 and f.linkrev() < limit:
return None
Here are various numbers (before this changeset/after this changesets)
source destination before after saved-time ratio
worth cases e66f24650daf 695dfb0f493b 1.062843 1.246369 -0.183526 1.172675
c979853a3b6a 8d60fe293e79 1.036985 1.196414 -0.159429 1.153743
22349fa2fc33 fbb1c9fd86c0 0.879926 1.038682 -0.158756 1.180420
682b98f3e672 a4878080a536 0.909952 1.063801 -0.153849 1.169074
5adabc9b9848 920958a93997 0.993622 1.147452 -0.153830 1.154817
worse 1% dbfbfcf077e9 aea8f2fd3593 1.016595 1.082999 -0.066404 1.065320
worse 5% c95f1ced15f2 7d29d5e39734 0.453694 0.471156 -0.017462 1.038488
worse 10% 3e144ed1d5b7 2aef0e942480 0.035140 0.037535 -0.002395 1.068156
worse 25% 321fc60db035 801748ba582a 0.009267 0.009325 -0.000058 1.006259
median 2088ce763fc2 e6991321d78b 0.000665 0.000651 0.000014 0.978947
best 25% 915631a97de6 385b31354be6 0.040743 0.040363 0.000380 0.990673
best 10% ad495c36a765 19c10384d3e7 0.431658 0.411490 0.020168 0.953278
best 5% d13ae7d283ae 813c99f810ac 1.141404 1.075346 0.066058 0.942126
best 1% 81593cb4a496 99ae11866969 1.833297 0.063823 1.769474 0.034813
best cases c3b14617fbd7 743a0fcaa4eb 1101.811740 2.735970 1099.075770 0.002483
c3b14617fbd7 9ba6ab77fd29 1116.753953 2.800729 1113.953224 0.002508
058b99d6e81f 57e249b7a3ea 1246.128485 3.042762 1243.085723 0.002442
9a8c361aab49 0354a250d371 1253.111894 3.085796 1250.026098 0.002463
442dbbc53c68 3ec1002a818c 1261.786294 3.138607 1258.647687 0.002487
As one can see, the average case is not really impacted. However, the worth case
we get after this changeset are much better than the one we had before it. We
have 30 pairs where improvements are above 10 minutes.
This reflect in the combined time for all pairs
before: 26256s
after: 1300s (-95%)
If we remove these pathological 30 cases, we still see a significant improvements:
before: 1631s
after: 1245s (-24%)
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 10 Oct 2019 03:49:33 +0200 |
parents | d7304434390f |
children | ebee234d952a |
line wrap: on
line source
#require no-chg #testcases bundle1 bundle2 #if bundle1 $ cat << EOF >> $HGRCPATH > [devel] > # This test is dedicated to interaction through old bundle > legacy.exchange = bundle1 > EOF #endif $ hg init test $ cd test $ echo a > a $ hg ci -Ama adding a $ cd .. $ hg clone test test2 updating to branch default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd test2 $ echo a >> a $ hg ci -mb $ req() { > hg $1 serve -p $HGPORT -d --pid-file=hg.pid -E errors.log > cat hg.pid >> $DAEMON_PIDS > hg --cwd ../test2 push http://localhost:$HGPORT/ > exitstatus=$? > killdaemons.py > echo % serve errors > cat errors.log > return $exitstatus > } $ cd ../test expect ssl error $ req pushing to http://localhost:$HGPORT/ searching for changes abort: HTTP Error 403: ssl required % serve errors [255] expect authorization error $ echo '[web]' > .hg/hgrc $ echo 'push_ssl = false' >> .hg/hgrc $ req pushing to http://localhost:$HGPORT/ searching for changes abort: authorization failed % serve errors [255] expect authorization error: must have authorized user $ echo 'allow_push = unperson' >> .hg/hgrc $ req pushing to http://localhost:$HGPORT/ searching for changes abort: authorization failed % serve errors [255] expect success $ cat > $TESTTMP/hook.sh <<'EOF' > echo "phase-move: $HG_NODE: $HG_OLDPHASE -> $HG_PHASE" > EOF #if bundle1 $ cat >> .hg/hgrc <<EOF > allow_push = * > [hooks] > changegroup = sh -c "printenv.py --line changegroup 0" > pushkey = sh -c "printenv.py --line pushkey 0" > txnclose-phase.test = sh $TESTTMP/hook.sh > EOF $ req "--debug --config extensions.blackbox=" listening at http://*:$HGPORT/ (bound to $LOCALIP:$HGPORT) (glob) (?) pushing to http://localhost:$HGPORT/ searching for changes remote: redirecting incoming bundle to */hg-unbundle-* (glob) remote: adding changesets remote: add changeset ba677d0156c1 remote: adding manifests remote: adding file changes remote: adding a revisions remote: updating the branch cache remote: added 1 changesets with 1 changes to 1 files remote: running hook txnclose-phase.test: sh $TESTTMP/hook.sh remote: phase-move: cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b: draft -> public remote: running hook txnclose-phase.test: sh $TESTTMP/hook.sh remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872: -> public remote: running hook changegroup: sh -c "printenv.py --line changegroup 0" remote: changegroup hook: HG_HOOKNAME=changegroup remote: HG_HOOKTYPE=changegroup remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_SOURCE=serve remote: HG_TXNID=TXN:$ID$ remote: HG_TXNNAME=serve remote: remote:http:$LOCALIP: (glob) remote: HG_URL=remote:http:$LOCALIP: (glob) remote: % serve errors $ hg rollback repository tip rolled back to revision 0 (undo serve) $ req "--debug --config server.streamunbundle=True --config extensions.blackbox=" listening at http://*:$HGPORT/ (bound to $LOCALIP:$HGPORT) (glob) (?) pushing to http://localhost:$HGPORT/ searching for changes remote: adding changesets remote: add changeset ba677d0156c1 remote: adding manifests remote: adding file changes remote: adding a revisions remote: updating the branch cache remote: added 1 changesets with 1 changes to 1 files remote: running hook txnclose-phase.test: sh $TESTTMP/hook.sh remote: phase-move: cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b: draft -> public remote: running hook txnclose-phase.test: sh $TESTTMP/hook.sh remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872: -> public remote: running hook changegroup: sh -c "printenv.py --line changegroup 0" remote: changegroup hook: HG_HOOKNAME=changegroup remote: HG_HOOKTYPE=changegroup remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_SOURCE=serve remote: HG_TXNID=TXN:$ID$ remote: HG_TXNNAME=serve remote: remote:http:$LOCALIP: (glob) remote: HG_URL=remote:http:$LOCALIP: (glob) remote: % serve errors $ hg rollback repository tip rolled back to revision 0 (undo serve) #endif #if bundle2 $ cat >> .hg/hgrc <<EOF > allow_push = * > [hooks] > changegroup = sh -c "printenv.py --line changegroup 0" > pushkey = sh -c "printenv.py --line pushkey 0" > txnclose-phase.test = sh $TESTTMP/hook.sh > EOF $ req pushing to http://localhost:$HGPORT/ searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: added 1 changesets with 1 changes to 1 files remote: phase-move: cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b: draft -> public remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872: -> public remote: changegroup hook: HG_BUNDLE2=1 remote: HG_HOOKNAME=changegroup remote: HG_HOOKTYPE=changegroup remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_SOURCE=serve remote: HG_TXNID=TXN:$ID$ remote: HG_TXNNAME=serve remote: HG_URL=remote:http:$LOCALIP: (glob) remote: % serve errors $ hg rollback repository tip rolled back to revision 0 (undo serve) #endif expect success, server lacks the httpheader capability $ CAP=httpheader $ . "$TESTDIR/notcapable" $ req pushing to http://localhost:$HGPORT/ searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: added 1 changesets with 1 changes to 1 files remote: phase-move: cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b: draft -> public remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872: -> public remote: changegroup hook: HG_HOOKNAME=changegroup (no-bundle2 !) remote: changegroup hook: HG_BUNDLE2=1 (bundle2 !) remote: HG_HOOKNAME=changegroup (bundle2 !) remote: HG_HOOKTYPE=changegroup remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_SOURCE=serve remote: HG_TXNID=TXN:$ID$ remote: HG_TXNNAME=serve remote: remote:http:$LOCALIP: (glob) (no-bundle2 !) remote: HG_URL=remote:http:$LOCALIP: (glob) remote: % serve errors $ hg rollback repository tip rolled back to revision 0 (undo serve) expect success, server lacks the unbundlehash capability $ CAP=unbundlehash $ . "$TESTDIR/notcapable" $ req pushing to http://localhost:$HGPORT/ searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: added 1 changesets with 1 changes to 1 files remote: phase-move: cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b: draft -> public remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872: -> public remote: changegroup hook: HG_HOOKNAME=changegroup (no-bundle2 !) remote: changegroup hook: HG_BUNDLE2=1 (bundle2 !) remote: HG_HOOKNAME=changegroup (bundle2 !) remote: HG_HOOKTYPE=changegroup remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_SOURCE=serve remote: HG_TXNID=TXN:$ID$ remote: HG_TXNNAME=serve remote: remote:http:$LOCALIP: (glob) (no-bundle2 !) remote: HG_URL=remote:http:$LOCALIP: (glob) remote: % serve errors $ hg rollback repository tip rolled back to revision 0 (undo serve) expect success, pre-d1b16a746db6 server supports the unbundle capability, but has no parameter $ cat <<EOF > notcapable-unbundleparam.py > from mercurial import extensions, httppeer > def capable(orig, self, name): > if name == 'unbundle': > return True > return orig(self, name) > def uisetup(ui): > extensions.wrapfunction(httppeer.httppeer, 'capable', capable) > EOF $ cp $HGRCPATH $HGRCPATH.orig $ cat <<EOF >> $HGRCPATH > [extensions] > notcapable-unbundleparam = `pwd`/notcapable-unbundleparam.py > EOF $ req pushing to http://localhost:$HGPORT/ searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: added 1 changesets with 1 changes to 1 files remote: phase-move: cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b: draft -> public remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872: -> public remote: changegroup hook: * (glob) remote: HG_HOOKNAME=changegroup (bundle2 !) remote: HG_HOOKTYPE=changegroup remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_SOURCE=serve remote: HG_TXNID=TXN:$ID$ remote: HG_TXNNAME=serve remote: remote:http:$LOCALIP: (glob) (no-bundle2 !) remote: HG_URL=remote:http:$LOCALIP: (glob) remote: % serve errors $ hg rollback repository tip rolled back to revision 0 (undo serve) $ mv $HGRCPATH.orig $HGRCPATH Test pushing to a publishing repository with a failing prepushkey hook $ cat > .hg/hgrc <<EOF > [web] > push_ssl = false > allow_push = * > [hooks] > prepushkey = sh -c "printenv.py --line prepushkey 1" > [devel] > legacy.exchange=phases > EOF #if bundle1 Bundle1 works because a) phases are updated as part of changegroup application and b) client checks phases after the "unbundle" command. Since it sees no phase changes are necessary, it doesn't send the "pushkey" command and the prepushkey hook never has to fire. $ req pushing to http://localhost:$HGPORT/ searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: added 1 changesets with 1 changes to 1 files % serve errors #endif #if bundle2 Bundle2 sends a "pushkey" bundle2 part. This runs as part of the transaction and fails the entire push. $ req pushing to http://localhost:$HGPORT/ searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: prepushkey hook: HG_BUNDLE2=1 remote: HG_HOOKNAME=prepushkey remote: HG_HOOKTYPE=prepushkey remote: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NAMESPACE=phases remote: HG_NEW=0 remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_OLD=1 remote: HG_PENDING=$TESTTMP/test remote: HG_PHASES_MOVED=1 remote: HG_SOURCE=serve remote: HG_TXNID=TXN:$ID$ remote: HG_TXNNAME=serve remote: HG_URL=remote:http:$LOCALIP: (glob) remote: remote: pushkey-abort: prepushkey hook exited with status 1 remote: transaction abort! remote: rollback completed abort: updating ba677d0156c1 to public failed % serve errors [255] #endif Now remove the failing prepushkey hook. $ cat >> .hg/hgrc <<EOF > [hooks] > prepushkey = sh -c "printenv.py --line prepushkey 0" > EOF We don't need to test bundle1 because it succeeded above. #if bundle2 $ req pushing to http://localhost:$HGPORT/ searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: prepushkey hook: HG_BUNDLE2=1 remote: HG_HOOKNAME=prepushkey remote: HG_HOOKTYPE=prepushkey remote: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NAMESPACE=phases remote: HG_NEW=0 remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_OLD=1 remote: HG_PENDING=$TESTTMP/test remote: HG_PHASES_MOVED=1 remote: HG_SOURCE=serve remote: HG_TXNID=TXN:$ID$ remote: HG_TXNNAME=serve remote: HG_URL=remote:http:$LOCALIP: (glob) remote: remote: added 1 changesets with 1 changes to 1 files % serve errors #endif $ hg --config extensions.strip= strip -r 1: saved backup bundle to $TESTTMP/test/.hg/strip-backup/ba677d0156c1-eea704d7-backup.hg Now do a variant of the above, except on a non-publishing repository $ cat >> .hg/hgrc <<EOF > [phases] > publish = false > [hooks] > prepushkey = sh -c "printenv.py --line prepushkey 1" > EOF #if bundle1 $ req pushing to http://localhost:$HGPORT/ searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: added 1 changesets with 1 changes to 1 files remote: prepushkey hook: HG_HOOKNAME=prepushkey remote: HG_HOOKTYPE=prepushkey remote: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NAMESPACE=phases remote: HG_NEW=0 remote: HG_OLD=1 remote: remote: pushkey-abort: prepushkey hook exited with status 1 updating ba677d0156c1 to public failed! % serve errors #endif #if bundle2 $ req pushing to http://localhost:$HGPORT/ searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: prepushkey hook: HG_BUNDLE2=1 remote: HG_HOOKNAME=prepushkey remote: HG_HOOKTYPE=prepushkey remote: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NAMESPACE=phases remote: HG_NEW=0 remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_OLD=1 remote: HG_PENDING=$TESTTMP/test remote: HG_PHASES_MOVED=1 remote: HG_SOURCE=serve remote: HG_TXNID=TXN:$ID$ remote: HG_TXNNAME=serve remote: HG_URL=remote:http:$LOCALIP: (glob) remote: remote: pushkey-abort: prepushkey hook exited with status 1 remote: transaction abort! remote: rollback completed abort: updating ba677d0156c1 to public failed % serve errors [255] #endif Make phases updates work $ cat >> .hg/hgrc <<EOF > [hooks] > prepushkey = sh -c "printenv.py --line prepushkey 0" > EOF #if bundle1 $ req pushing to http://localhost:$HGPORT/ searching for changes no changes found remote: prepushkey hook: HG_HOOKNAME=prepushkey remote: HG_HOOKTYPE=prepushkey remote: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NAMESPACE=phases remote: HG_NEW=0 remote: HG_OLD=1 remote: % serve errors [1] #endif #if bundle2 $ req pushing to http://localhost:$HGPORT/ searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: prepushkey hook: HG_BUNDLE2=1 remote: HG_HOOKNAME=prepushkey remote: HG_HOOKTYPE=prepushkey remote: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NAMESPACE=phases remote: HG_NEW=0 remote: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 remote: HG_OLD=1 remote: HG_PENDING=$TESTTMP/test remote: HG_PHASES_MOVED=1 remote: HG_SOURCE=serve remote: HG_TXNID=TXN:$ID$ remote: HG_TXNNAME=serve remote: HG_URL=remote:http:$LOCALIP: (glob) remote: remote: added 1 changesets with 1 changes to 1 files % serve errors #endif $ hg --config extensions.strip= strip -r 1: saved backup bundle to $TESTTMP/test/.hg/strip-backup/ba677d0156c1-eea704d7-backup.hg #if bundle2 $ cat > .hg/hgrc <<EOF > [web] > push_ssl = false > allow_push = * > [experimental] > httppostargs=true > EOF $ req pushing to http://localhost:$HGPORT/ searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: added 1 changesets with 1 changes to 1 files % serve errors #endif $ cd .. Pushing via hgwebdir works $ hg init hgwebdir $ cd hgwebdir $ echo 0 > a $ hg -q commit -A -m initial $ cd .. $ cat > web.conf << EOF > [paths] > / = * > [web] > push_ssl = false > allow_push = * > EOF $ hg serve --web-conf web.conf -p $HGPORT -d --pid-file hg.pid $ cat hg.pid >> $DAEMON_PIDS $ hg clone http://localhost:$HGPORT/hgwebdir hgwebdir-local requesting all changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files new changesets 98a3f8f02ba7 updating to branch default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd hgwebdir-local $ echo commit > a $ hg commit -m 'local commit' $ hg push pushing to http://localhost:$HGPORT/hgwebdir searching for changes remote: adding changesets remote: adding manifests remote: adding file changes remote: added 1 changesets with 1 changes to 1 files $ killdaemons.py $ cd ..