changeset 14770:95a8c0f5dd3f stable

tests: add basic commandserver test
author Idan Kamara <idankk86@gmail.com>
date Wed, 29 Jun 2011 15:49:35 +0300
parents 9adce4b38ed1
children 0cc66f13bea0
files tests/test-commandserver.py tests/test-commandserver.py.out
diffstat 2 files changed, 168 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /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
+