tests: invoke printenv.py via sh -c for test portability stable
authorFUJIWARA Katsunori <foozy@lares.dti.ne.jp>
Sat, 29 Oct 2016 02:44:45 +0900
branchstable
changeset 33727 34a5f6c66bc5a13381a68d08f73d858916167836
parent 33726 3afde791dce192f38d8a228ed8e49397e353837e
child 33728 fe612ab5eeff700b808a1d85013fa3472517a3d6
push id365
push usergszorc@mozilla.com
push dateTue, 01 Nov 2016 02:33:44 +0000
tests: invoke printenv.py via sh -c for test portability On Windows platform, invoking printenv.py directly via hook is problematic, because: - unless binding between *.py suffix and python runtime, application selector dialog is displayed, and running test is blocked at each printenv.py invocations - it isn't safe to assume binding between *.py suffix and python runtime, because application binding is easily broken For example, installing IDE (VisualStudio with Python Tools, or so) often requires binding between source files and IDE itself. This patch invokes printenv.py via sh -c for test portability. This is a kind of follow up for d19787db6fe0, which eliminated explicit "python" for printenv.py. There are already other 'sh -c "printenv.py"' in *.t files, and this fix should be reasonable. This changes were confirmed in cases below: - without any application binding for *.py suffix - with binding between *.py suffix and VisualStudio This patch also replaces "echo + redirection" style with "heredoc" style, because: - hook command line is parsed by cmd.exe as shell at first, and - single quotation can't quote arguments on cmd.exe, therefore, - "printenv.py foobar" should be quoted by double quotation, but - nested quoting (or tricky escaping) isn't readable
tests/test-bundle.t
tests/test-hook.t
tests/test-http-bundle1.t
tests/test-http.t
tests/test-https.t
tests/test-push-http-bundle1.t
tests/test-push-http.t
tests/test-ssh-bundle1.t
tests/test-ssh.t
tests/test-static-http.t
--- a/tests/test-bundle.t
+++ b/tests/test-bundle.t
@@ -211,18 +211,20 @@ Make sure bundlerepo doesn't leak tempfi
   $ ls .hg
   00changelog.i
   cache
   requires
   store
 
 Pull ../full.hg into empty (with hook)
 
-  $ echo "[hooks]" >> .hg/hgrc
-  $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > [hooks]
+  > changegroup = sh -c "printenv.py changegroup"
+  > EOF
 
 doesn't work (yet ?)
 
 hg -R bundle://../full.hg verify
 
   $ hg pull bundle://../full.hg
   pulling from bundle:../full.hg
   requesting all changes
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -11,19 +11,19 @@ commit hooks can see env vars
   $ cd a
   $ cat > .hg/hgrc <<EOF
   > [hooks]
   > commit = sh -c "HG_LOCAL= HG_TAG= printenv.py commit"
   > commit.b = sh -c "HG_LOCAL= HG_TAG= printenv.py commit.b"
   > precommit = sh -c  "HG_LOCAL= HG_NODE= HG_TAG= printenv.py precommit"
   > pretxncommit = sh -c "HG_LOCAL= HG_TAG= printenv.py pretxncommit"
   > pretxncommit.tip = hg -q tip
-  > pre-identify = printenv.py pre-identify 1
-  > pre-cat = printenv.py pre-cat
-  > post-cat = printenv.py post-cat
+  > pre-identify = sh -c "printenv.py pre-identify 1"
+  > pre-cat = sh -c "printenv.py pre-cat"
+  > post-cat = sh -c "printenv.py post-cat"
   > pretxnopen = sh -c "HG_LOCAL= HG_TAG= printenv.py pretxnopen"
   > pretxnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py pretxnclose"
   > txnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py txnclose"
   > txnabort.0 = python:$TESTTMP/txnabort.checkargs.py:showargs
   > txnabort.1 = sh -c "HG_LOCAL= HG_TAG= printenv.py txnabort"
   > txnclose.checklock = sh -c "hg debuglock > /dev/null"
   > EOF
   $ echo a > a
@@ -42,19 +42,19 @@ commit hooks can see env vars
   updating to branch default
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd ../b
 
 changegroup hooks can see env vars
 
   $ cat > .hg/hgrc <<EOF
   > [hooks]
-  > prechangegroup = printenv.py prechangegroup
-  > changegroup = printenv.py changegroup
-  > incoming = printenv.py incoming
+  > prechangegroup = sh -c "printenv.py prechangegroup"
+  > changegroup = sh -c "printenv.py changegroup"
+  > incoming = sh -c "printenv.py incoming"
   > EOF
 
 pretxncommit and commit hooks can see both parents of merge
 
   $ cd ../a
   $ echo b >> a
   $ hg commit -m a1 -d "1 0"
   precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
@@ -117,17 +117,17 @@ test generic hooks
   incoming hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=file:$TESTTMP/a (glob)
   incoming hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=file:$TESTTMP/a (glob)
   (run 'hg update' to get a working copy)
 
 tag hooks can see env vars
 
   $ cd ../a
   $ cat >> .hg/hgrc <<EOF
-  > pretag = printenv.py pretag
+  > pretag = sh -c "printenv.py pretag"
   > tag = sh -c "HG_PARENT1= HG_PARENT2= printenv.py tag"
   > EOF
   $ hg tag -d '3 0' a
   pretag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
   precommit hook: HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
   pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
   pretxncommit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PENDING=$TESTTMP/a
   4:539e4b31b6dc
@@ -137,33 +137,37 @@ tag hooks can see env vars
   commit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
   commit.b hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
   $ hg tag -l la
   pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
   tag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
 
 pretag hook can forbid tagging
 
-  $ echo "pretag.forbid = printenv.py pretag.forbid 1" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > pretag.forbid = sh -c "printenv.py pretag.forbid 1"
+  > EOF
   $ hg tag -d '4 0' fa
   pretag hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
   pretag.forbid hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
   abort: pretag.forbid hook exited with status 1
   [255]
   $ hg tag -l fla
   pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
   pretag.forbid hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
   abort: pretag.forbid hook exited with status 1
   [255]
 
 pretxncommit hook can see changeset, can roll back txn, changeset no
 more there after
 
-  $ echo "pretxncommit.forbid0 = hg tip -q" >> .hg/hgrc
-  $ echo "pretxncommit.forbid1 = printenv.py pretxncommit.forbid 1" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > pretxncommit.forbid0 = sh -c "hg tip -q"
+  > pretxncommit.forbid1 = sh -c "printenv.py pretxncommit.forbid 1"
+  > EOF
   $ echo z > z
   $ hg add z
   $ hg -q tip
   4:539e4b31b6dc
   $ hg commit -m 'fail' -d '4 0'
   precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
   pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
   pretxncommit hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
@@ -191,76 +195,88 @@ more there after
   undo
   undo.backup.fncache
   undo.backupfiles
   undo.phaseroots
 
 
 precommit hook can prevent commit
 
-  $ echo "precommit.forbid = printenv.py precommit.forbid 1" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > precommit.forbid = sh -c "printenv.py precommit.forbid 1"
+  > EOF
   $ hg commit -m 'fail' -d '4 0'
   precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
   precommit.forbid hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
   abort: precommit.forbid hook exited with status 1
   [255]
   $ hg -q tip
   4:539e4b31b6dc
 
 preupdate hook can prevent update
 
-  $ echo "preupdate = printenv.py preupdate" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > preupdate = sh -c "printenv.py preupdate"
+  > EOF
   $ hg update 1
   preupdate hook: HG_PARENT1=ab228980c14d
   0 files updated, 0 files merged, 2 files removed, 0 files unresolved
 
 update hook
 
-  $ echo "update = printenv.py update" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > update = sh -c "printenv.py update"
+  > EOF
   $ hg update
   preupdate hook: HG_PARENT1=539e4b31b6dc
   update hook: HG_ERROR=0 HG_PARENT1=539e4b31b6dc
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
 pushkey hook
 
-  $ echo "pushkey = printenv.py pushkey" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > pushkey = sh -c "printenv.py pushkey"
+  > EOF
   $ cd ../b
   $ hg bookmark -r null foo
   $ hg push -B foo ../a
   pushing to ../a
   searching for changes
   no changes found
   pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=push (glob)
   pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_PENDING=$TESTTMP/a HG_SOURCE=push HG_TXNID=TXN:* HG_TXNNAME=push HG_URL=file:$TESTTMP/a (glob)
   pushkey hook: HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_RET=1
   txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_SOURCE=push HG_TXNID=TXN:* HG_TXNNAME=push HG_URL=file:$TESTTMP/a (glob)
   exporting bookmark foo
   [1]
   $ cd ../a
 
 listkeys hook
 
-  $ echo "listkeys = printenv.py listkeys" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > listkeys = sh -c "printenv.py listkeys"
+  > EOF
   $ hg bookmark -r null bar
   pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=bookmark (glob)
   pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_PENDING=$TESTTMP/a HG_TXNID=TXN:* HG_TXNNAME=bookmark (glob)
   txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:* HG_TXNNAME=bookmark (glob)
   $ cd ../b
   $ hg pull -B bar ../a
   pulling from ../a
   listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
   no changes found
   listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
   adding remote bookmark bar
   $ cd ../a
 
 test that prepushkey can prevent incoming keys
 
-  $ echo "prepushkey = printenv.py prepushkey.forbid 1" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > prepushkey = sh -c "printenv.py prepushkey.forbid 1"
+  > EOF
   $ cd ../b
   $ hg bookmark -r null baz
   $ hg push -B baz ../a
   pushing to ../a
   searching for changes
   listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
   listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
   no changes found
@@ -268,17 +284,19 @@ test that prepushkey can prevent incomin
   prepushkey.forbid hook: HG_BUNDLE2=1 HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_SOURCE=push HG_TXNID=TXN:* HG_URL=file:$TESTTMP/a (glob)
   pushkey-abort: prepushkey hook exited with status 1
   abort: exporting bookmark baz failed!
   [255]
   $ cd ../a
 
 test that prelistkeys can prevent listing keys
 
-  $ echo "prelistkeys = printenv.py prelistkeys.forbid 1" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > prelistkeys = sh -c "printenv.py prelistkeys.forbid 1"
+  > EOF
   $ hg bookmark -r null quux
   pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=bookmark (glob)
   pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_PENDING=$TESTTMP/a HG_TXNID=TXN:* HG_TXNNAME=bookmark (glob)
   txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:* HG_TXNNAME=bookmark (glob)
   $ cd ../b
   $ hg pull -B quux ../a
   pulling from ../a
   prelistkeys.forbid hook: HG_NAMESPACE=bookmarks
@@ -289,32 +307,32 @@ test that prelistkeys can prevent listin
 
 prechangegroup hook can prevent incoming changes
 
   $ cd ../b
   $ hg -q tip
   3:07f3376c1e65
   $ cat > .hg/hgrc <<EOF
   > [hooks]
-  > prechangegroup.forbid = printenv.py prechangegroup.forbid 1
+  > prechangegroup.forbid = sh -c "printenv.py prechangegroup.forbid 1"
   > EOF
   $ hg pull ../a
   pulling from ../a
   searching for changes
   prechangegroup.forbid hook: HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=file:$TESTTMP/a (glob)
   abort: prechangegroup.forbid hook exited with status 1
   [255]
 
 pretxnchangegroup hook can see incoming changes, can roll back txn,
 incoming changes no longer there after
 
   $ cat > .hg/hgrc <<EOF
   > [hooks]
   > pretxnchangegroup.forbid0 = hg tip -q
-  > pretxnchangegroup.forbid1 = printenv.py pretxnchangegroup.forbid 1
+  > pretxnchangegroup.forbid1 = sh -c "printenv.py pretxnchangegroup.forbid 1"
   > EOF
   $ hg pull ../a
   pulling from ../a
   searching for changes
   adding changesets
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
@@ -327,18 +345,18 @@ incoming changes no longer there after
   $ hg -q tip
   3:07f3376c1e65
 
 outgoing hooks can see env vars
 
   $ rm .hg/hgrc
   $ cat > ../a/.hg/hgrc <<EOF
   > [hooks]
-  > preoutgoing = printenv.py preoutgoing
-  > outgoing = printenv.py outgoing
+  > preoutgoing = sh -c "printenv.py preoutgoing"
+  > outgoing = sh -c "printenv.py outgoing"
   > EOF
   $ hg pull ../a
   pulling from ../a
   searching for changes
   preoutgoing hook: HG_SOURCE=pull
   outgoing hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_SOURCE=pull
   adding changesets
   adding manifests
@@ -346,43 +364,47 @@ outgoing hooks can see env vars
   added 1 changesets with 1 changes to 1 files
   adding remote bookmark quux
   (run 'hg update' to get a working copy)
   $ hg rollback
   repository tip rolled back to revision 3 (undo pull)
 
 preoutgoing hook can prevent outgoing changes
 
-  $ echo "preoutgoing.forbid = printenv.py preoutgoing.forbid 1" >> ../a/.hg/hgrc
+  $ cat >> ../a/.hg/hgrc <<EOF
+  > preoutgoing.forbid = sh -c "printenv.py preoutgoing.forbid 1"
+  > EOF
   $ hg pull ../a
   pulling from ../a
   searching for changes
   preoutgoing hook: HG_SOURCE=pull
   preoutgoing.forbid hook: HG_SOURCE=pull
   abort: preoutgoing.forbid hook exited with status 1
   [255]
 
 outgoing hooks work for local clones
 
   $ cd ..
   $ cat > a/.hg/hgrc <<EOF
   > [hooks]
-  > preoutgoing = printenv.py preoutgoing
-  > outgoing = printenv.py outgoing
+  > preoutgoing = sh -c "printenv.py preoutgoing"
+  > outgoing = sh -c "printenv.py outgoing"
   > EOF
   $ hg clone a c
   preoutgoing hook: HG_SOURCE=clone
   outgoing hook: HG_NODE=0000000000000000000000000000000000000000 HG_SOURCE=clone
   updating to branch default
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ rm -rf c
 
 preoutgoing hook can prevent outgoing changes for local clones
 
-  $ echo "preoutgoing.forbid = printenv.py preoutgoing.forbid 1" >> a/.hg/hgrc
+  $ cat >> a/.hg/hgrc <<EOF
+  > preoutgoing.forbid = sh -c "printenv.py preoutgoing.forbid 1"
+  > EOF
   $ hg clone a zzz
   preoutgoing hook: HG_SOURCE=clone
   preoutgoing.forbid hook: HG_SOURCE=clone
   abort: preoutgoing.forbid hook exited with status 1
   [255]
 
   $ cd "$TESTTMP/b"
 
@@ -745,17 +767,17 @@ new tags must be visible in pretxncommit
   ['a', 'foo', 'tip']
 
 post-init hooks must not crash (issue4983)
 This also creates the `to` repo for the next test block.
 
   $ cd ..
   $ cat << EOF >> hgrc-with-post-init-hook
   > [hooks]
-  > post-init = printenv.py post-init
+  > post-init = sh -c "printenv.py post-init"
   > EOF
   $ HGRCPATH=hgrc-with-post-init-hook hg init to
   post-init hook: HG_ARGS=init to HG_OPTS={'insecure': None, 'remotecmd': '', 'ssh': ''} HG_PATS=['to'] HG_RESULT=0
 
 new commits must be visible in pretxnchangegroup (issue3428)
 
   $ echo '[hooks]' >> to/.hg/hgrc
   $ echo 'prechangegroup = hg --traceback tip' >> to/.hg/hgrc
--- a/tests/test-http-bundle1.t
+++ b/tests/test-http-bundle1.t
@@ -122,18 +122,20 @@ incoming via HTTP
   comparing with http://localhost:$HGPORT1/
   searching for changes
   2
   $ cd ..
 
 pull
 
   $ cd copy-pull
-  $ echo '[hooks]' >> .hg/hgrc
-  $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > [hooks]
+  > changegroup = sh -c "printenv.py changegroup"
+  > EOF
   $ hg pull
   pulling from http://localhost:$HGPORT1/
   searching for changes
   adding changesets
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
   changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=http://localhost:$HGPORT1/ (glob)
--- a/tests/test-http.t
+++ b/tests/test-http.t
@@ -113,18 +113,20 @@ incoming via HTTP
   comparing with http://localhost:$HGPORT1/
   searching for changes
   2
   $ cd ..
 
 pull
 
   $ cd copy-pull
-  $ echo '[hooks]' >> .hg/hgrc
-  $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > [hooks]
+  > changegroup = sh -c "printenv.py changegroup"
+  > EOF
   $ hg pull
   pulling from http://localhost:$HGPORT1/
   searching for changes
   adding changesets
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
   changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=http://localhost:$HGPORT1/ (glob)
--- a/tests/test-https.t
+++ b/tests/test-https.t
@@ -198,18 +198,20 @@ Inability to verify peer certificate wil
   $ echo bar > bar
   $ hg commit -A -d '1 0' -m 2
   adding bar
   $ cd ..
 
 pull without cacert
 
   $ cd copy-pull
-  $ echo '[hooks]' >> .hg/hgrc
-  $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > [hooks]
+  > changegroup = sh -c "printenv.py changegroup"
+  > EOF
   $ hg pull $DISABLECACERTS
   pulling from https://localhost:$HGPORT/
   warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
   abort: unable to verify security of localhost (no loaded CA certificates); refusing to connect
   (see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error or set hostsecurity.localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e to trust this server)
   [255]
 
   $ hg pull --insecure
--- a/tests/test-push-http-bundle1.t
+++ b/tests/test-push-http-bundle1.t
@@ -61,20 +61,22 @@ expect authorization error: must have au
   pushing to http://localhost:$HGPORT/
   searching for changes
   abort: authorization failed
   % serve errors
   [255]
 
 expect success
 
-  $ echo 'allow_push = *' >> .hg/hgrc
-  $ echo '[hooks]' >> .hg/hgrc
-  $ echo "changegroup = printenv.py changegroup 0" >> .hg/hgrc
-  $ echo "pushkey = printenv.py pushkey 0" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > allow_push = *
+  > [hooks]
+  > changegroup = sh -c "printenv.py changegroup 0"
+  > pushkey = sh -c "printenv.py pushkey 0"
+  > 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: changegroup hook: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:http:127.0.0.1: (glob)
@@ -146,30 +148,32 @@ has no parameter
 
 expect push success, phase change failure
 
   $ cat > .hg/hgrc <<EOF
   > [web]
   > push_ssl = false
   > allow_push = *
   > [hooks]
-  > prepushkey = printenv.py prepushkey 1
+  > prepushkey = sh -c "printenv.py prepushkey 1"
   > 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
 
 expect phase change success
 
-  $ echo "prepushkey = printenv.py prepushkey 0" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > prepushkey = sh -c "printenv.py prepushkey 0"
+  > EOF
   $ req
   pushing to http://localhost:$HGPORT/
   searching for changes
   no changes found
   % serve errors
   [1]
   $ hg rollback
   repository tip rolled back to revision 0 (undo serve)
--- a/tests/test-push-http.t
+++ b/tests/test-push-http.t
@@ -51,20 +51,22 @@ expect authorization error: must have au
   pushing to http://localhost:$HGPORT/
   searching for changes
   abort: authorization failed
   % serve errors
   [255]
 
 expect success
 
-  $ echo 'allow_push = *' >> .hg/hgrc
-  $ echo '[hooks]' >> .hg/hgrc
-  $ echo "changegroup = printenv.py changegroup 0" >> .hg/hgrc
-  $ echo "pushkey = printenv.py pushkey 0" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > allow_push = *
+  > [hooks]
+  > changegroup = sh -c "printenv.py changegroup 0"
+  > pushkey = sh -c "printenv.py pushkey 0"
+  > 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: pushkey hook: HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NAMESPACE=phases HG_NEW=0 HG_OLD=1 HG_RET=1
@@ -109,17 +111,17 @@ expect success, server lacks the unbundl
 
 expect push success, phase change failure
 
   $ cat > .hg/hgrc <<EOF
   > [web]
   > push_ssl = false
   > allow_push = *
   > [hooks]
-  > prepushkey = printenv.py prepushkey 1
+  > prepushkey = sh -c "printenv.py prepushkey 1"
   > 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
@@ -128,17 +130,19 @@ expect push success, phase change failur
   remote: transaction abort!
   remote: rollback completed
   abort: updating ba677d0156c1 to public failed
   % serve errors
   [255]
 
 expect phase change success
 
-  $ echo "prepushkey = printenv.py prepushkey 0" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > prepushkey = sh -c "printenv.py prepushkey 0"
+  > 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: prepushkey hook: HG_BUNDLE2=1 HG_KEY=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NAMESPACE=phases HG_NEW=0 HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_OLD=1 HG_PENDING=$TESTTMP/test HG_PHASES_MOVED=1 HG_SOURCE=serve HG_TXNID=TXN:* HG_URL=remote:http:127.0.0.1: (glob)
--- a/tests/test-ssh-bundle1.t
+++ b/tests/test-ssh-bundle1.t
@@ -33,17 +33,17 @@ insert a closed branch (issue4428)
 
 configure for serving
 
   $ cat <<EOF > .hg/hgrc
   > [server]
   > uncompressed = True
   > 
   > [hooks]
-  > changegroup = printenv.py changegroup-in-remote 0 ../dummylog
+  > changegroup = sh -c "printenv.py changegroup-in-remote 0 ../dummylog"
   > EOF
   $ cd ..
 
 repo not found error
 
   $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
   remote: abort: repository nonexistent not found!
   abort: no suitable response from remote hg!
@@ -109,18 +109,20 @@ verify
 
   $ cd local
   $ hg verify
   checking changesets
   checking manifests
   crosschecking files in changesets and manifests
   checking files
   2 files, 3 changesets, 2 total revisions
-  $ echo '[hooks]' >> .hg/hgrc
-  $ echo "changegroup = printenv.py changegroup-in-local 0 ../dummylog" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > [hooks]
+  > changegroup = sh -c "printenv.py changegroup-in-local 0 ../dummylog"
+  > EOF
 
 empty default pull
 
   $ hg paths
   default = ssh://user@dummy/remote
   $ hg pull -e "python \"$TESTDIR/dummyssh\""
   pulling from ssh://user@dummy/remote
   searching for changes
--- a/tests/test-ssh.t
+++ b/tests/test-ssh.t
@@ -27,17 +27,17 @@ insert a closed branch (issue4428)
 
 configure for serving
 
   $ cat <<EOF > .hg/hgrc
   > [server]
   > uncompressed = True
   > 
   > [hooks]
-  > changegroup = printenv.py changegroup-in-remote 0 ../dummylog
+  > changegroup = sh -c "printenv.py changegroup-in-remote 0 ../dummylog"
   > EOF
   $ cd ..
 
 repo not found error
 
   $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
   remote: abort: repository nonexistent not found!
   abort: no suitable response from remote hg!
@@ -103,18 +103,20 @@ verify
 
   $ cd local
   $ hg verify
   checking changesets
   checking manifests
   crosschecking files in changesets and manifests
   checking files
   2 files, 3 changesets, 2 total revisions
-  $ echo '[hooks]' >> .hg/hgrc
-  $ echo "changegroup = printenv.py changegroup-in-local 0 ../dummylog" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > [hooks]
+  > changegroup = sh -c "printenv.py changegroup-in-local 0 ../dummylog"
+  > EOF
 
 empty default pull
 
   $ hg paths
   default = ssh://user@dummy/remote
   $ hg pull -e "python \"$TESTDIR/dummyssh\""
   pulling from ssh://user@dummy/remote
   searching for changes
--- a/tests/test-static-http.t
+++ b/tests/test-static-http.t
@@ -48,18 +48,20 @@ one pull
   $ echo baz > quux
   $ hg commit -A -mtest2
   adding quux
 
 check for HTTP opener failures when cachefile does not exist
 
   $ rm .hg/cache/*
   $ cd ../local
-  $ echo '[hooks]' >> .hg/hgrc
-  $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc
+  $ cat >> .hg/hgrc <<EOF
+  > [hooks]
+  > changegroup = sh -c "printenv.py changegroup"
+  > EOF
   $ hg pull
   pulling from static-http://localhost:$HGPORT/remote
   searching for changes
   adding changesets
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
   changegroup hook: HG_NODE=4ac2e3648604439c580c69b09ec9d93a88d93432 HG_NODE_LAST=4ac2e3648604439c580c69b09ec9d93a88d93432 HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=http://localhost:$HGPORT/remote (glob)