--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-commandserver.py Wed Jun 29 15:49:35 2011 +0300
@@ -0,0 +1,130 @@
+import sys, os, struct, subprocess, cStringIO, re
+
+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:
+ raise EOFError()
+ channel, length = struct.unpack('>cI', data)
+ if channel in 'IL':
+ return channel, length
+ else:
+ return channel, server.stdout.read(length)
+
+def runcommand(server, args, output=sys.stdout, error=sys.stderr, input=None):
+ 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':
+ output.write(data)
+ 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':
+ return struct.unpack('>i', data)[0]
+ else:
+ print "unexpected channel %c: %r" % (ch, data)
+ if ch.isupper():
+ return
+
+def check(func, repopath=None):
+ 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
+ print '%c, %r' % (ch, re.sub('encoding: [a-zA-Z0-9-]+', 'encoding: ***', data))
+
+ # 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'])
+
+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'])
+
+if __name__ == '__main__':
+ os.system('hg init')
+
+ check(hellomessage)
+ check(unknowncommand)
+ check(checkruncommand)
+ check(inputeof)
+ check(serverinput)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-commandserver.py.out Wed Jun 29 15:49:35 2011 +0300
@@ -0,0 +1,38 @@
+o, 'capabilities: getencoding runcommand\nencoding: ***'
+000000000000 tip
+abort: unknown command unknowncommand
+Mercurial Distributed SCM
+
+basic commands:
+
+ add add the specified files on the next commit
+ annotate show changeset information by line for each file
+ clone make a copy of an existing repository
+ commit commit the specified files or all outstanding changes
+ diff diff repository (or selected files)
+ export dump the header and diffs for one or more changesets
+ forget forget the specified files on the next commit
+ init create a new repository in the given directory
+ log show revision history of entire repository or files
+ merge merge working directory with another revision
+ pull pull changes from the specified source
+ push push changes to the specified destination
+ remove remove the specified files on the next commit
+ serve start stand-alone webserver
+ status show changed files in the working directory
+ summary summarize working directory state
+ update update working directory (or switch revisions)
+
+use "hg help" for the full list of commands or "hg -v" for details
+000000000000
+000000000000 tip
+000000000000
+000000000000 tip
+server exit code = 1
+applying patch from stdin
+changeset: 0:eff892de26ec
+tag: tip
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: 1
+