##// END OF EJS Templates
extensions: register functions always at loading extension (issue5601)...
extensions: register functions always at loading extension (issue5601) Before this patch, functions defined in extensions are registered via extra loaders only in _dispatch(). Therefore, loading extensions in other code paths like below omits registration of functions. - WSGI service - operation across repositories (e.g. subrepo) - test-duplicateoptions.py, using extensions.loadall() directly To register functions always at loading new extension, this patch moves implementation for extra loading from dispatch._dispatch() to extensions.loadall(). AFAIK, only commands module causes cyclic dependency between extensions module, but this patch imports all related modules just before extra loading in loadall(), in order to centralize them. This patch makes extensions.py depend on many other modules, even though extensions.py itself doesn't. It should be avoided if possible, but I don't have any better idea. Some other places like below aren't reasonable for extra loading, IMHO. - specific function in newly added module: existing callers of extensions.loadall() should invoke it, too - hg.repository() or so: no-repo commands aren't covered by this. BTW, this patch removes _loaded.add(name) on relocation, because dispatch._loaded is used only for extraloaders (for similar reason, "exts" variable is removed, too).

File last commit:

r32940:75be1499 default
r33052:45b0e9d0 default
Show More
test-chg.t
203 lines | 4.8 KiB | text/troff | Tads3Lexer
Yuya Nishihara
test-chg: run only with chg...
r29274 #require chg
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275 $ cp $HGRCPATH $HGRCPATH.orig
Jun Wu
chgserver: handle ParseError during validate...
r28516 init repo
Yuya Nishihara
test-chg: run only with chg...
r29274 $ chg init foo
Jun Wu
chgserver: handle ParseError during validate...
r28516 $ cd foo
ill-formed config
Yuya Nishihara
test-chg: run only with chg...
r29274 $ chg status
Jun Wu
chgserver: handle ParseError during validate...
r28516 $ echo '=brokenconfig' >> $HGRCPATH
Yuya Nishihara
test-chg: run only with chg...
r29274 $ chg status
Jun Wu
chgserver: handle ParseError during validate...
r28516 hg: parse error at * (glob)
[255]
Jun Wu
chgserver: remove _clearenvaliases...
r29088
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275 $ cp $HGRCPATH.orig $HGRCPATH
Jun Wu
chg: support long socket path...
r30677
long socket path
$ sockpath=$TESTTMP/this/path/should/be/longer/than/one-hundred-and-seven/characters/where/107/is/the/typical/size/limit/of/unix-domain-socket
$ mkdir -p $sockpath
$ bakchgsockname=$CHGSOCKNAME
$ CHGSOCKNAME=$sockpath/server
$ export CHGSOCKNAME
$ chg root
$TESTTMP/foo
$ rm -rf $sockpath
$ CHGSOCKNAME=$bakchgsockname
$ export CHGSOCKNAME
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275 $ cd ..
Yuya Nishihara
chg: refactor ui.system() to be partly overridden...
r31107 editor
------
$ cat >> pushbuffer.py <<EOF
> def reposetup(ui, repo):
> repo.ui.pushbuffer(subproc=True)
> EOF
$ chg init editor
$ cd editor
by default, system() should be redirected to the client:
$ touch foo
$ CHGDEBUG= HGEDITOR=cat chg ci -Am channeled --edit 2>&1 \
> | egrep "HG:|run 'cat"
chg: debug: run 'cat "*"' at '$TESTTMP/editor' (glob)
HG: Enter commit message. Lines beginning with 'HG:' are removed.
HG: Leave message empty to abort commit.
HG: --
HG: user: test
HG: branch 'default'
HG: added foo
but no redirection should be made if output is captured:
$ touch bar
$ CHGDEBUG= HGEDITOR=cat chg ci -Am bufferred --edit \
> --config extensions.pushbuffer="$TESTTMP/pushbuffer.py" 2>&1 \
> | egrep "HG:|run 'cat"
[1]
check that commit commands succeeded:
$ hg log -T '{rev}:{desc}\n'
1:bufferred
0:channeled
$ cd ..
Yuya Nishihara
pager: wrap _runcommand() no matter if stdout is redirected...
r30847 pager
-----
$ cat >> fakepager.py <<EOF
> import sys
> for line in sys.stdin:
> sys.stdout.write('paged! %r\n' % line)
> EOF
enable pager extension globally, but spawns the master server with no tty:
$ chg init pager
$ cd pager
$ cat >> $HGRCPATH <<EOF
> [extensions]
> pager =
> [pager]
Augie Fackler
cleanup: use $PYTHON to run python in many more tests...
r32940 > pager = $PYTHON $TESTTMP/fakepager.py
Yuya Nishihara
pager: wrap _runcommand() no matter if stdout is redirected...
r30847 > EOF
$ chg version > /dev/null
$ touch foo
$ chg ci -qAm foo
pager should be enabled if the attached client has a tty:
$ chg log -l1 -q --config ui.formatted=True
paged! '0:1f7b0de80e11\n'
$ chg log -l1 -q --config ui.formatted=False
0:1f7b0de80e11
Jun Wu
chg: always wait for pager...
r31890 chg waits for pager if runcommand raises
$ cat > $TESTTMP/crash.py <<EOF
Yuya Nishihara
registrar: move cmdutil.command to registrar module (API)...
r32337 > from mercurial import registrar
Jun Wu
chg: always wait for pager...
r31890 > cmdtable = {}
Yuya Nishihara
registrar: move cmdutil.command to registrar module (API)...
r32337 > command = registrar.command(cmdtable)
Jun Wu
chg: always wait for pager...
r31890 > @command('crash')
> def pagercrash(ui, repo, *pats, **opts):
> ui.write('going to crash\n')
> raise Exception('.')
> EOF
$ cat > $TESTTMP/fakepager.py <<EOF
> import sys, time
> for line in iter(sys.stdin.readline, ''):
> if 'crash' in line: # only interested in lines containing 'crash'
> # if chg exits when pager is sleeping (incorrectly), the output
> # will be captured by the next test case
> time.sleep(1)
> sys.stdout.write('crash-pager: %s' % line)
> EOF
$ cat >> .hg/hgrc <<EOF
> [extensions]
> crash = $TESTTMP/crash.py
> EOF
$ chg crash --pager=on --config ui.formatted=True 2>/dev/null
crash-pager: going to crash
[255]
Yuya Nishihara
pager: wrap _runcommand() no matter if stdout is redirected...
r30847 $ cd ..
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275 server lifecycle
----------------
chg server should be restarted on code change, and old server will shut down
automatically. In this test, we use the following time parameters:
- "sleep 1" to make mtime different
- "sleep 2" to notice mtime change (polling interval is 1 sec)
set up repository with an extension:
$ chg init extreload
$ cd extreload
$ touch dummyext.py
$ cat <<EOF >> .hg/hgrc
> [extensions]
> dummyext = dummyext.py
> EOF
isolate socket directory for stable result:
$ OLDCHGSOCKNAME=$CHGSOCKNAME
$ mkdir chgsock
$ CHGSOCKNAME=`pwd`/chgsock/server
warm up server:
$ CHGDEBUG= chg log 2>&1 | egrep 'instruction|start'
Jun Wu
chg: start server at a unique address...
r30620 chg: debug: start cmdserver at $TESTTMP/extreload/chgsock/server.* (glob)
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275
new server should be started if extension modified:
$ sleep 1
$ touch dummyext.py
$ CHGDEBUG= chg log 2>&1 | egrep 'instruction|start'
chg: debug: instruction: unlink $TESTTMP/extreload/chgsock/server-* (glob)
chg: debug: instruction: reconnect
Jun Wu
chg: start server at a unique address...
r30620 chg: debug: start cmdserver at $TESTTMP/extreload/chgsock/server.* (glob)
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275
old server will shut down, while new server should still be reachable:
$ sleep 2
$ CHGDEBUG= chg log 2>&1 | (egrep 'instruction|start' || true)
socket file should never be unlinked by old server:
(simulates unowned socket by updating mtime, which makes sure server exits
at polling cycle)
$ ls chgsock/server-*
chgsock/server-* (glob)
$ touch chgsock/server-*
$ sleep 2
$ ls chgsock/server-*
chgsock/server-* (glob)
since no server is reachable from socket file, new server should be started:
(this test makes sure that old server shut down automatically)
$ CHGDEBUG= chg log 2>&1 | egrep 'instruction|start'
Jun Wu
chg: start server at a unique address...
r30620 chg: debug: start cmdserver at $TESTTMP/extreload/chgsock/server.* (glob)
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275
shut down servers and restore environment:
$ rm -R chgsock
$ CHGSOCKNAME=$OLDCHGSOCKNAME
$ cd ..