##// END OF EJS Templates
py3: port test-batching.py to python3...
Augie Fackler -
r41366:b81ca9a3 default
parent child Browse files
Show More
@@ -26,6 +26,7 b' test-backwards-remove.t'
26 test-bad-extension.t
26 test-bad-extension.t
27 test-bad-pull.t
27 test-bad-pull.t
28 test-basic.t
28 test-basic.t
29 test-batching.py
29 test-bdiff.py
30 test-bdiff.py
30 test-bheads.t
31 test-bheads.t
31 test-bisect.t
32 test-bisect.t
@@ -11,25 +11,28 b' import contextlib'
11
11
12 from mercurial import (
12 from mercurial import (
13 localrepo,
13 localrepo,
14 pycompat,
14 wireprotov1peer,
15 wireprotov1peer,
16 )
15
17
16 )
18 def bprint(*bs):
19 print(*[pycompat.sysstr(b) for b in bs])
17
20
18 # equivalent of repo.repository
21 # equivalent of repo.repository
19 class thing(object):
22 class thing(object):
20 def hello(self):
23 def hello(self):
21 return "Ready."
24 return b"Ready."
22
25
23 # equivalent of localrepo.localrepository
26 # equivalent of localrepo.localrepository
24 class localthing(thing):
27 class localthing(thing):
25 def foo(self, one, two=None):
28 def foo(self, one, two=None):
26 if one:
29 if one:
27 return "%s and %s" % (one, two,)
30 return b"%s and %s" % (one, two,)
28 return "Nope"
31 return b"Nope"
29 def bar(self, b, a):
32 def bar(self, b, a):
30 return "%s und %s" % (b, a,)
33 return b"%s und %s" % (b, a,)
31 def greet(self, name=None):
34 def greet(self, name=None):
32 return "Hello, %s" % name
35 return b"Hello, %s" % name
33
36
34 @contextlib.contextmanager
37 @contextlib.contextmanager
35 def commandexecutor(self):
38 def commandexecutor(self):
@@ -43,27 +46,27 b' class localthing(thing):'
43 def use(it):
46 def use(it):
44
47
45 # Direct call to base method shared between client and server.
48 # Direct call to base method shared between client and server.
46 print(it.hello())
49 bprint(it.hello())
47
50
48 # Direct calls to proxied methods. They cause individual roundtrips.
51 # Direct calls to proxied methods. They cause individual roundtrips.
49 print(it.foo("Un", two="Deux"))
52 bprint(it.foo(b"Un", two=b"Deux"))
50 print(it.bar("Eins", "Zwei"))
53 bprint(it.bar(b"Eins", b"Zwei"))
51
54
52 # Batched call to a couple of proxied methods.
55 # Batched call to a couple of proxied methods.
53
56
54 with it.commandexecutor() as e:
57 with it.commandexecutor() as e:
55 ffoo = e.callcommand('foo', {'one': 'One', 'two': 'Two'})
58 ffoo = e.callcommand(b'foo', {b'one': b'One', b'two': b'Two'})
56 fbar = e.callcommand('bar', {'b': 'Eins', 'a': 'Zwei'})
59 fbar = e.callcommand(b'bar', {b'b': b'Eins', b'a': b'Zwei'})
57 fbar2 = e.callcommand('bar', {'b': 'Uno', 'a': 'Due'})
60 fbar2 = e.callcommand(b'bar', {b'b': b'Uno', b'a': b'Due'})
58
61
59 print(ffoo.result())
62 bprint(ffoo.result())
60 print(fbar.result())
63 bprint(fbar.result())
61 print(fbar2.result())
64 bprint(fbar2.result())
62
65
63 # local usage
66 # local usage
64 mylocal = localthing()
67 mylocal = localthing()
65 print()
68 print()
66 print("== Local")
69 bprint(b"== Local")
67 use(mylocal)
70 use(mylocal)
68
71
69 # demo remoting; mimicks what wireproto and HTTP/SSH do
72 # demo remoting; mimicks what wireproto and HTTP/SSH do
@@ -72,16 +75,16 b' use(mylocal)'
72
75
73 def escapearg(plain):
76 def escapearg(plain):
74 return (plain
77 return (plain
75 .replace(':', '::')
78 .replace(b':', b'::')
76 .replace(',', ':,')
79 .replace(b',', b':,')
77 .replace(';', ':;')
80 .replace(b';', b':;')
78 .replace('=', ':='))
81 .replace(b'=', b':='))
79 def unescapearg(escaped):
82 def unescapearg(escaped):
80 return (escaped
83 return (escaped
81 .replace(':=', '=')
84 .replace(b':=', b'=')
82 .replace(':;', ';')
85 .replace(b':;', b';')
83 .replace(':,', ',')
86 .replace(b':,', b',')
84 .replace('::', ':'))
87 .replace(b'::', b':'))
85
88
86 # server side
89 # server side
87
90
@@ -90,27 +93,28 b' class server(object):'
90 def __init__(self, local):
93 def __init__(self, local):
91 self.local = local
94 self.local = local
92 def _call(self, name, args):
95 def _call(self, name, args):
93 args = dict(arg.split('=', 1) for arg in args)
96 args = dict(arg.split(b'=', 1) for arg in args)
94 return getattr(self, name)(**args)
97 return getattr(self, name)(**args)
95 def perform(self, req):
98 def perform(self, req):
96 print("REQ:", req)
99 bprint(b"REQ:", req)
97 name, args = req.split('?', 1)
100 name, args = req.split(b'?', 1)
98 args = args.split('&')
101 args = args.split(b'&')
99 vals = dict(arg.split('=', 1) for arg in args)
102 vals = dict(arg.split(b'=', 1) for arg in args)
100 res = getattr(self, name)(**vals)
103 res = getattr(self, pycompat.sysstr(name))(**pycompat.strkwargs(vals))
101 print(" ->", res)
104 bprint(b" ->", res)
102 return res
105 return res
103 def batch(self, cmds):
106 def batch(self, cmds):
104 res = []
107 res = []
105 for pair in cmds.split(';'):
108 for pair in cmds.split(b';'):
106 name, args = pair.split(':', 1)
109 name, args = pair.split(b':', 1)
107 vals = {}
110 vals = {}
108 for a in args.split(','):
111 for a in args.split(b','):
109 if a:
112 if a:
110 n, v = a.split('=')
113 n, v = a.split(b'=')
111 vals[n] = unescapearg(v)
114 vals[n] = unescapearg(v)
112 res.append(escapearg(getattr(self, name)(**vals)))
115 res.append(escapearg(getattr(self, pycompat.sysstr(name))(
113 return ';'.join(res)
116 **pycompat.strkwargs(vals))))
117 return b';'.join(res)
114 def foo(self, one, two):
118 def foo(self, one, two):
115 return mangle(self.local.foo(unmangle(one), unmangle(two)))
119 return mangle(self.local.foo(unmangle(one), unmangle(two)))
116 def bar(self, b, a):
120 def bar(self, b, a):
@@ -124,25 +128,25 b' myserver = server(mylocal)'
124 # equivalent of wireproto.encode/decodelist, that is, type-specific marshalling
128 # equivalent of wireproto.encode/decodelist, that is, type-specific marshalling
125 # here we just transform the strings a bit to check we're properly en-/decoding
129 # here we just transform the strings a bit to check we're properly en-/decoding
126 def mangle(s):
130 def mangle(s):
127 return ''.join(chr(ord(c) + 1) for c in s)
131 return b''.join(pycompat.bytechr(ord(c) + 1) for c in pycompat.bytestr(s))
128 def unmangle(s):
132 def unmangle(s):
129 return ''.join(chr(ord(c) - 1) for c in s)
133 return b''.join(pycompat.bytechr(ord(c) - 1) for c in pycompat.bytestr(s))
130
134
131 # equivalent of wireproto.wirerepository and something like http's wire format
135 # equivalent of wireproto.wirerepository and something like http's wire format
132 class remotething(thing):
136 class remotething(thing):
133 def __init__(self, server):
137 def __init__(self, server):
134 self.server = server
138 self.server = server
135 def _submitone(self, name, args):
139 def _submitone(self, name, args):
136 req = name + '?' + '&'.join(['%s=%s' % (n, v) for n, v in args])
140 req = name + b'?' + b'&'.join([b'%s=%s' % (n, v) for n, v in args])
137 return self.server.perform(req)
141 return self.server.perform(req)
138 def _submitbatch(self, cmds):
142 def _submitbatch(self, cmds):
139 req = []
143 req = []
140 for name, args in cmds:
144 for name, args in cmds:
141 args = ','.join(n + '=' + escapearg(v) for n, v in args)
145 args = b','.join(n + b'=' + escapearg(v) for n, v in args)
142 req.append(name + ':' + args)
146 req.append(name + b':' + args)
143 req = ';'.join(req)
147 req = b';'.join(req)
144 res = self._submitone('batch', [('cmds', req,)])
148 res = self._submitone(b'batch', [(b'cmds', req,)])
145 for r in res.split(';'):
149 for r in res.split(b';'):
146 yield r
150 yield r
147
151
148 @contextlib.contextmanager
152 @contextlib.contextmanager
@@ -155,7 +159,7 b' class remotething(thing):'
155
159
156 @wireprotov1peer.batchable
160 @wireprotov1peer.batchable
157 def foo(self, one, two=None):
161 def foo(self, one, two=None):
158 encargs = [('one', mangle(one),), ('two', mangle(two),)]
162 encargs = [(b'one', mangle(one),), (b'two', mangle(two),)]
159 encresref = wireprotov1peer.future()
163 encresref = wireprotov1peer.future()
160 yield encargs, encresref
164 yield encargs, encresref
161 yield unmangle(encresref.value)
165 yield unmangle(encresref.value)
@@ -163,18 +167,18 b' class remotething(thing):'
163 @wireprotov1peer.batchable
167 @wireprotov1peer.batchable
164 def bar(self, b, a):
168 def bar(self, b, a):
165 encresref = wireprotov1peer.future()
169 encresref = wireprotov1peer.future()
166 yield [('b', mangle(b),), ('a', mangle(a),)], encresref
170 yield [(b'b', mangle(b),), (b'a', mangle(a),)], encresref
167 yield unmangle(encresref.value)
171 yield unmangle(encresref.value)
168
172
169 # greet is coded directly. It therefore does not support batching. If it
173 # greet is coded directly. It therefore does not support batching. If it
170 # does appear in a batch, the batch is split around greet, and the call to
174 # does appear in a batch, the batch is split around greet, and the call to
171 # greet is done in its own roundtrip.
175 # greet is done in its own roundtrip.
172 def greet(self, name=None):
176 def greet(self, name=None):
173 return unmangle(self._submitone('greet', [('name', mangle(name),)]))
177 return unmangle(self._submitone(b'greet', [(b'name', mangle(name),)]))
174
178
175 # demo remote usage
179 # demo remote usage
176
180
177 myproxy = remotething(myserver)
181 myproxy = remotething(myserver)
178 print()
182 print()
179 print("== Remote")
183 bprint(b"== Remote")
180 use(myproxy)
184 use(myproxy)
General Comments 0
You need to be logged in to leave comments. Login now