##// END OF EJS Templates
cmdserver: forcibly use L channel to read password input (issue3161)...
cmdserver: forcibly use L channel to read password input (issue3161) Command server is designed to use the channel protocol even if the server process is accessible to tty, whereas vanilla hg should be able to read password from tty in that case. So it isn't enough to swap sys.stdin: # works only if the server process is detached from the console sys.stdin = self.fin getpass.getpass('') sys.stdin = oldin or test isatty: # vanilla hg can't talk to tty if stdin is redirected if self._isatty(self.fin): return getpass.getpass('') else: ... Since ui.nontty flag is undocumented and command-server channels don't provide isatty(), this change won't affect the other uses of ui._isatty(). issue3161 also suggests to provide some context of messages. I think it can be implemented by using the generic templating function.

File last commit:

r21195:9336bc7d stable
r21195:9336bc7d stable
Show More
test-commandserver.py
358 lines | 9.7 KiB | text/x-python | PythonLexer
/ tests / test-commandserver.py
Idan Kamara
cmdserver: take repo.baseui as our ui...
r14882 import sys, os, struct, subprocess, cStringIO, re, shutil
Idan Kamara
tests: add basic commandserver test
r14770
def connect(path=None):
cmdline = ['hg', 'serve', '--cmdserver', 'pipe']
if path:
cmdline += ['-R', path]
server = subprocess.Popen(cmdline, stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
return server
def writeblock(server, data):
server.stdin.write(struct.pack('>I', len(data)))
server.stdin.write(data)
server.stdin.flush()
def readchannel(server):
data = server.stdout.read(5)
if not data:
Brodie Rao
cleanup: "raise SomeException()" -> "raise SomeException"
r16687 raise EOFError
Idan Kamara
tests: add basic commandserver test
r14770 channel, length = struct.unpack('>cI', data)
if channel in 'IL':
return channel, length
else:
return channel, server.stdout.read(length)
Brendan Cully
tests: fix test-commandserver phase . output for windows
r19132 def sep(text):
return text.replace('\\', '/')
def runcommand(server, args, output=sys.stdout, error=sys.stderr, input=None,
outfilter=lambda x: x):
Mads Kiilerich
tests: make test-commandserver.py output readable
r15541 print ' runcommand', ' '.join(args)
Idan Kamara
test-commandserver: flush stdout
r16117 sys.stdout.flush()
Idan Kamara
tests: add basic commandserver test
r14770 server.stdin.write('runcommand\n')
writeblock(server, '\0'.join(args))
if not input:
input = cStringIO.StringIO()
while True:
ch, data = readchannel(server)
if ch == 'o':
Brendan Cully
tests: fix test-commandserver phase . output for windows
r19132 output.write(outfilter(data))
Idan Kamara
tests: add basic commandserver test
r14770 output.flush()
elif ch == 'e':
error.write(data)
error.flush()
elif ch == 'I':
writeblock(server, input.read(data))
elif ch == 'L':
writeblock(server, input.readline(data))
elif ch == 'r':
Yuya Nishihara
cmdserver: include non-zero return code of runcommand in test output
r20630 ret, = struct.unpack('>i', data)
if ret != 0:
print ' [%d]' % ret
return ret
Idan Kamara
tests: add basic commandserver test
r14770 else:
print "unexpected channel %c: %r" % (ch, data)
if ch.isupper():
return
def check(func, repopath=None):
Mads Kiilerich
tests: make test-commandserver.py output readable
r15541 print
print 'testing %s:' % func.__name__
print
Idan Kamara
test-commandserver: flush stdout
r16117 sys.stdout.flush()
Idan Kamara
tests: add basic commandserver test
r14770 server = connect(repopath)
try:
return func(server)
finally:
server.stdin.close()
server.wait()
def unknowncommand(server):
server.stdin.write('unknowncommand\n')
def hellomessage(server):
ch, data = readchannel(server)
# escaping python tests output not supported
Brodie Rao
cleanup: eradicate long lines
r16683 print '%c, %r' % (ch, re.sub('encoding: [a-zA-Z0-9-]+', 'encoding: ***',
data))
Idan Kamara
tests: add basic commandserver test
r14770
# run an arbitrary command to make sure the next thing the server sends
# isn't part of the hello message
runcommand(server, ['id'])
def checkruncommand(server):
# hello block
readchannel(server)
# no args
runcommand(server, [])
# global options
runcommand(server, ['id', '--quiet'])
# make sure global options don't stick through requests
runcommand(server, ['id'])
# --config
runcommand(server, ['id', '--config', 'ui.quiet=True'])
# make sure --config doesn't stick
runcommand(server, ['id'])
Yuya Nishihara
cmdserver: mask return code of runcommand in the same way as dispatch.run...
r20631 # negative return code should be masked
runcommand(server, ['id', '-runknown'])
Idan Kamara
tests: add basic commandserver test
r14770 def inputeof(server):
readchannel(server)
server.stdin.write('runcommand\n')
# close stdin while server is waiting for input
server.stdin.close()
# server exits with 1 if the pipe closed while reading the command
print 'server exit code =', server.wait()
def serverinput(server):
readchannel(server)
patch = """
# HG changeset patch
# User test
# Date 0 0
# Node ID c103a3dec114d882c98382d684d8af798d09d857
# Parent 0000000000000000000000000000000000000000
1
diff -r 000000000000 -r c103a3dec114 a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/a Thu Jan 01 00:00:00 1970 +0000
@@ -0,0 +1,1 @@
+1
"""
runcommand(server, ['import', '-'], input=cStringIO.StringIO(patch))
runcommand(server, ['log'])
Idan Kamara
cmdserver: restore old working dir after dispatch when we have --cwd
r14864 def cwd(server):
""" check that --cwd doesn't persist between requests """
readchannel(server)
os.mkdir('foo')
Mads Kiilerich
tests: make test-commandserver.py independent of line ending and slash direction
r15542 f = open('foo/bar', 'wb')
Idan Kamara
test-commandserver: explicitly close opened file
r14880 f.write('a')
f.close()
Idan Kamara
cmdserver: restore old working dir after dispatch when we have --cwd
r14864 runcommand(server, ['--cwd', 'foo', 'st', 'bar'])
runcommand(server, ['st', 'foo/bar'])
os.remove('foo/bar')
Idan Kamara
cmdserver: take repo.baseui as our ui...
r14882 def localhgrc(server):
""" check that local configs for the cached repo aren't inherited when -R
is used """
readchannel(server)
Brodie Rao
cleanup: eradicate long lines
r16683 # the cached repo local hgrc contains ui.foo=bar, so showconfig should
# show it
Idan Kamara
cmdserver: take repo.baseui as our ui...
r14882 runcommand(server, ['showconfig'])
# but not for this repo
runcommand(server, ['init', 'foo'])
Mads Kiilerich
tests: make test-commandserver.py independent of line ending and slash direction
r15542 runcommand(server, ['-R', 'foo', 'showconfig', 'ui', 'defaults'])
Idan Kamara
cmdserver: take repo.baseui as our ui...
r14882 shutil.rmtree('foo')
Idan Kamara
hooks: redirect stdout/err/in to the ui descriptors when calling python hooks...
r14889 def hook(**args):
print 'hook talking'
print 'now try to read something: %r' % sys.stdin.read()
def hookoutput(server):
readchannel(server)
runcommand(server, ['--config',
Brodie Rao
cleanup: eradicate long lines
r16683 'hooks.pre-identify=python:test-commandserver.hook',
'id'],
Idan Kamara
hooks: redirect stdout/err/in to the ui descriptors when calling python hooks...
r14889 input=cStringIO.StringIO('some input'))
Idan Kamara
cmdserver: repo.invalidate() on every runcommand...
r14939 def outsidechanges(server):
readchannel(server)
Mads Kiilerich
tests: make test-commandserver.py independent of line ending and slash direction
r15542 f = open('a', 'ab')
f.write('a\n')
f.close()
Idan Kamara
cmdserver: invalidate the dirstate when running commands (issue3271)...
r16114 runcommand(server, ['status'])
Mads Kiilerich
tests: make test-commandserver.py independent of line ending and slash direction
r15542 os.system('hg ci -Am2')
Idan Kamara
cmdserver: repo.invalidate() on every runcommand...
r14939 runcommand(server, ['tip'])
Idan Kamara
cmdserver: invalidate the dirstate when running commands (issue3271)...
r16114 runcommand(server, ['status'])
Idan Kamara
cmdserver: repo.invalidate() on every runcommand...
r14939
def bookmarks(server):
readchannel(server)
runcommand(server, ['bookmarks'])
# changes .hg/bookmarks
os.system('hg bookmark -i bm1')
os.system('hg bookmark -i bm2')
runcommand(server, ['bookmarks'])
# changes .hg/bookmarks.current
os.system('hg upd bm1 -q')
runcommand(server, ['bookmarks'])
Idan Kamara
scmutil: update cached copy when filecached attribute is assigned (issue3263)...
r16115 runcommand(server, ['bookmarks', 'bm3'])
f = open('a', 'ab')
f.write('a\n')
f.close()
runcommand(server, ['commit', '-Amm'])
runcommand(server, ['bookmarks'])
Idan Kamara
cmdserver: repo.invalidate() on every runcommand...
r14939 def tagscache(server):
readchannel(server)
runcommand(server, ['id', '-t', '-r', '0'])
os.system('hg tag -r 0 foo')
runcommand(server, ['id', '-t', '-r', '0'])
Idan Kamara
test-commandserver: test that phase data is being refreshed
r15989 def setphase(server):
readchannel(server)
runcommand(server, ['phase', '-r', '.'])
os.system('hg phase -r . -p')
runcommand(server, ['phase', '-r', '.'])
Idan Kamara
localrepo: clear _filecache on rollback (issue3261)...
r16116 def rollback(server):
readchannel(server)
runcommand(server, ['phase', '-r', '.', '-p'])
f = open('a', 'ab')
f.write('a\n')
f.close()
runcommand(server, ['commit', '-Am.'])
runcommand(server, ['rollback'])
runcommand(server, ['phase', '-r', '.'])
Idan Kamara
dirstate: filecacheify _branch...
r16201 def branch(server):
readchannel(server)
runcommand(server, ['branch'])
os.system('hg branch foo')
runcommand(server, ['branch'])
os.system('hg branch default')
Idan Kamara
dirstate: filecacheify _ignore (issue3278)...
r16202 def hgignore(server):
readchannel(server)
f = open('.hgignore', 'ab')
f.write('')
f.close()
runcommand(server, ['commit', '-Am.'])
f = open('ignored-file', 'ab')
f.write('')
f.close()
f = open('.hgignore', 'ab')
f.write('ignored-file')
f.close()
runcommand(server, ['status', '-i', '-u'])
Idan Kamara
localrepo: always write the filtered phasecache when nodes are destroyed (issue3827)...
r18757 def phasecacheafterstrip(server):
readchannel(server)
# create new head, 5:731265503d86
runcommand(server, ['update', '-C', '0'])
f = open('a', 'ab')
f.write('a\n')
f.close()
runcommand(server, ['commit', '-Am.', 'a'])
runcommand(server, ['log', '-Gq'])
# make it public; draft marker moves to 4:7966c8e3734d
runcommand(server, ['phase', '-p', '.'])
Brendan Cully
tests: fix test-commandserver phase . output for windows
r19132 # load _phasecache.phaseroots
runcommand(server, ['phase', '.'], outfilter=sep)
Idan Kamara
localrepo: always write the filtered phasecache when nodes are destroyed (issue3827)...
r18757
# strip 1::4 outside server
Matt Mackall
tests: quiet strip to avoid commandserver pathsep issue
r19166 os.system('hg -q --config extensions.mq= strip 1')
Idan Kamara
localrepo: always write the filtered phasecache when nodes are destroyed (issue3827)...
r18757
# shouldn't raise "7966c8e3734d: no node!"
runcommand(server, ['branches'])
Julien Cristau
dispatch: take --hidden from individual commands into account...
r20330 def obsolete(server):
readchannel(server)
runcommand(server, ['up', 'null'])
runcommand(server, ['phase', '-df', 'tip'])
Simon Heimberg
tests: on windows, run command explicitly in sh for working command substitution...
r20396 cmd = 'hg debugobsolete `hg log -r tip --template {node}`'
if os.name == 'nt':
cmd = 'sh -c "%s"' % cmd # run in sh, not cmd.exe
os.system(cmd)
Julien Cristau
dispatch: take --hidden from individual commands into account...
r20330 runcommand(server, ['log', '--hidden'])
runcommand(server, ['log'])
Yuya Nishihara
cmdserver: reload mq on each runcommand request to avoid corruption...
r20628 def mqoutsidechanges(server):
readchannel(server)
# load repo.mq
runcommand(server, ['qapplied'])
os.system('hg qnew 0.diff')
# repo.mq should be invalidated
runcommand(server, ['qapplied'])
Yuya Nishihara
cmdserver: recreate mq object on runcommand in case queue path was changed...
r20629 runcommand(server, ['qpop', '--all'])
os.system('hg qqueue --create foo')
# repo.mq should be recreated to point to new queue
runcommand(server, ['qqueue', '--active'])
Yuya Nishihara
cmdserver: forcibly use L channel to read password input (issue3161)...
r21195 def getpass(server):
readchannel(server)
runcommand(server, ['debuggetpass', '--config', 'ui.interactive=True'],
input=cStringIO.StringIO('1234\n'))
Yuya Nishihara
cmdserver: allow to start server without repository...
r20650 def startwithoutrepo(server):
readchannel(server)
runcommand(server, ['init', 'repo2'])
runcommand(server, ['id', '-R', 'repo2'])
Idan Kamara
tests: add basic commandserver test
r14770 if __name__ == '__main__':
Yuya Nishihara
cmdserver: prepare test for starting server without repository
r20649 os.system('hg init repo')
os.chdir('repo')
Idan Kamara
tests: add basic commandserver test
r14770
check(hellomessage)
check(unknowncommand)
check(checkruncommand)
check(inputeof)
check(serverinput)
Idan Kamara
cmdserver: restore old working dir after dispatch when we have --cwd
r14864 check(cwd)
Idan Kamara
cmdserver: take repo.baseui as our ui...
r14882
hgrc = open('.hg/hgrc', 'a')
hgrc.write('[ui]\nfoo=bar\n')
hgrc.close()
check(localhgrc)
Idan Kamara
hooks: redirect stdout/err/in to the ui descriptors when calling python hooks...
r14889 check(hookoutput)
Idan Kamara
cmdserver: repo.invalidate() on every runcommand...
r14939 check(outsidechanges)
check(bookmarks)
check(tagscache)
Idan Kamara
test-commandserver: test that phase data is being refreshed
r15989 check(setphase)
Idan Kamara
localrepo: clear _filecache on rollback (issue3261)...
r16116 check(rollback)
Idan Kamara
dirstate: filecacheify _branch...
r16201 check(branch)
Idan Kamara
dirstate: filecacheify _ignore (issue3278)...
r16202 check(hgignore)
Idan Kamara
localrepo: always write the filtered phasecache when nodes are destroyed (issue3827)...
r18757 check(phasecacheafterstrip)
Julien Cristau
dispatch: take --hidden from individual commands into account...
r20330 obs = open('obs.py', 'w')
obs.write('import mercurial.obsolete\nmercurial.obsolete._enabled = True\n')
obs.close()
hgrc = open('.hg/hgrc', 'a')
hgrc.write('[extensions]\nobs=obs.py\n')
hgrc.close()
check(obsolete)
Yuya Nishihara
cmdserver: reload mq on each runcommand request to avoid corruption...
r20628 hgrc = open('.hg/hgrc', 'a')
hgrc.write('[extensions]\nmq=\n')
hgrc.close()
check(mqoutsidechanges)
Yuya Nishihara
cmdserver: forcibly use L channel to read password input (issue3161)...
r21195 dbg = open('dbgui.py', 'w')
dbg.write('from mercurial import cmdutil, commands\n'
'commands.norepo += " debuggetpass"\n'
'cmdtable = {}\n'
'command = cmdutil.command(cmdtable)\n'
'@command("debuggetpass")\n'
'def debuggetpass(ui):\n'
' ui.write("%s\\n" % ui.getpass())\n')
dbg.close()
hgrc = open('.hg/hgrc', 'a')
hgrc.write('[extensions]\ndbgui=dbgui.py\n')
hgrc.close()
check(getpass)
Yuya Nishihara
cmdserver: allow to start server without repository...
r20650
os.chdir('..')
check(hellomessage)
check(startwithoutrepo)