tests/test-commandserver.py
branchstable
changeset 14770 95a8c0f5dd3f
child 14864 1b872599f39f
--- /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)