tests/test-commandserver.py
changeset 14813 53ed7b560564
parent 14770 95a8c0f5dd3f
child 14864 1b872599f39f
equal deleted inserted replaced
14804:f70629146f79 14813:53ed7b560564
       
     1 import sys, os, struct, subprocess, cStringIO, re
       
     2 
       
     3 def connect(path=None):
       
     4     cmdline = ['hg', 'serve', '--cmdserver', 'pipe']
       
     5     if path:
       
     6         cmdline += ['-R', path]
       
     7 
       
     8     server = subprocess.Popen(cmdline, stdin=subprocess.PIPE,
       
     9                               stdout=subprocess.PIPE)
       
    10 
       
    11     return server
       
    12 
       
    13 def writeblock(server, data):
       
    14     server.stdin.write(struct.pack('>I', len(data)))
       
    15     server.stdin.write(data)
       
    16     server.stdin.flush()
       
    17 
       
    18 def readchannel(server):
       
    19     data = server.stdout.read(5)
       
    20     if not data:
       
    21         raise EOFError()
       
    22     channel, length = struct.unpack('>cI', data)
       
    23     if channel in 'IL':
       
    24         return channel, length
       
    25     else:
       
    26         return channel, server.stdout.read(length)
       
    27 
       
    28 def runcommand(server, args, output=sys.stdout, error=sys.stderr, input=None):
       
    29     server.stdin.write('runcommand\n')
       
    30     writeblock(server, '\0'.join(args))
       
    31 
       
    32     if not input:
       
    33         input = cStringIO.StringIO()
       
    34 
       
    35     while True:
       
    36         ch, data = readchannel(server)
       
    37         if ch == 'o':
       
    38             output.write(data)
       
    39             output.flush()
       
    40         elif ch == 'e':
       
    41             error.write(data)
       
    42             error.flush()
       
    43         elif ch == 'I':
       
    44             writeblock(server, input.read(data))
       
    45         elif ch == 'L':
       
    46             writeblock(server, input.readline(data))
       
    47         elif ch == 'r':
       
    48             return struct.unpack('>i', data)[0]
       
    49         else:
       
    50             print "unexpected channel %c: %r" % (ch, data)
       
    51             if ch.isupper():
       
    52                 return
       
    53 
       
    54 def check(func, repopath=None):
       
    55     server = connect(repopath)
       
    56     try:
       
    57         return func(server)
       
    58     finally:
       
    59         server.stdin.close()
       
    60         server.wait()
       
    61 
       
    62 def unknowncommand(server):
       
    63     server.stdin.write('unknowncommand\n')
       
    64 
       
    65 def hellomessage(server):
       
    66     ch, data = readchannel(server)
       
    67     # escaping python tests output not supported
       
    68     print '%c, %r' % (ch, re.sub('encoding: [a-zA-Z0-9-]+', 'encoding: ***', data))
       
    69 
       
    70     # run an arbitrary command to make sure the next thing the server sends
       
    71     # isn't part of the hello message
       
    72     runcommand(server, ['id'])
       
    73 
       
    74 def checkruncommand(server):
       
    75     # hello block
       
    76     readchannel(server)
       
    77 
       
    78     # no args
       
    79     runcommand(server, [])
       
    80 
       
    81     # global options
       
    82     runcommand(server, ['id', '--quiet'])
       
    83 
       
    84     # make sure global options don't stick through requests
       
    85     runcommand(server, ['id'])
       
    86 
       
    87     # --config
       
    88     runcommand(server, ['id', '--config', 'ui.quiet=True'])
       
    89 
       
    90     # make sure --config doesn't stick
       
    91     runcommand(server, ['id'])
       
    92 
       
    93 def inputeof(server):
       
    94     readchannel(server)
       
    95     server.stdin.write('runcommand\n')
       
    96     # close stdin while server is waiting for input
       
    97     server.stdin.close()
       
    98 
       
    99     # server exits with 1 if the pipe closed while reading the command
       
   100     print 'server exit code =', server.wait()
       
   101 
       
   102 def serverinput(server):
       
   103     readchannel(server)
       
   104 
       
   105     patch = """
       
   106 # HG changeset patch
       
   107 # User test
       
   108 # Date 0 0
       
   109 # Node ID c103a3dec114d882c98382d684d8af798d09d857
       
   110 # Parent  0000000000000000000000000000000000000000
       
   111 1
       
   112 
       
   113 diff -r 000000000000 -r c103a3dec114 a
       
   114 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
       
   115 +++ b/a	Thu Jan 01 00:00:00 1970 +0000
       
   116 @@ -0,0 +1,1 @@
       
   117 +1
       
   118 """
       
   119 
       
   120     runcommand(server, ['import', '-'], input=cStringIO.StringIO(patch))
       
   121     runcommand(server, ['log'])
       
   122 
       
   123 if __name__ == '__main__':
       
   124     os.system('hg init')
       
   125 
       
   126     check(hellomessage)
       
   127     check(unknowncommand)
       
   128     check(checkruncommand)
       
   129     check(inputeof)
       
   130     check(serverinput)