comparison tests/test-commandserver.py @ 14770:95a8c0f5dd3f stable

tests: add basic commandserver test
author Idan Kamara <idankk86@gmail.com>
date Wed, 29 Jun 2011 15:49:35 +0300
parents
children 1b872599f39f
comparison
equal deleted inserted replaced
14769:9adce4b38ed1 14770:95a8c0f5dd3f
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)