##// END OF EJS Templates
tests: use () instead of \ to wrap lines...
tests: use () instead of \ to wrap lines This should auto-format more consistently, and is slightly more typical Python. Differential Revision: https://phab.mercurial-scm.org/D5992

File last commit:

r41366:b81ca9a3 default
r41924:15d3facf default
Show More
test-batching.py
184 lines | 5.5 KiB | text/x-python | PythonLexer
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 # test-batching.py - tests for transparent command batching
#
# Copyright 2011 Peter Arrenbrecht <peter@arrenbrecht.ch>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Robert Stanca
py3: use print_function in test-batching.py
r28732 from __future__ import absolute_import, print_function
Yuya Nishihara
test-batching: stop direct symbol import of mercurial modules...
r28800
Gregory Szorc
wireproto: remove iterbatch() from peer interface (API)...
r37651 import contextlib
Yuya Nishihara
test-batching: stop direct symbol import of mercurial modules...
r28800 from mercurial import (
Gregory Szorc
peer: scatter module to the wind (API)...
r37633 localrepo,
Augie Fackler
py3: port test-batching.py to python3...
r41366 pycompat,
Gregory Szorc
wireproto: move version 1 peer functionality to standalone module (API)...
r37632 wireprotov1peer,
Augie Fackler
py3: port test-batching.py to python3...
r41366 )
Gregory Szorc
peer: scatter module to the wind (API)...
r37633
Augie Fackler
py3: port test-batching.py to python3...
r41366 def bprint(*bs):
print(*[pycompat.sysstr(b) for b in bs])
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
# equivalent of repo.repository
class thing(object):
def hello(self):
Augie Fackler
py3: port test-batching.py to python3...
r41366 return b"Ready."
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
# equivalent of localrepo.localrepository
class localthing(thing):
def foo(self, one, two=None):
if one:
Augie Fackler
py3: port test-batching.py to python3...
r41366 return b"%s and %s" % (one, two,)
return b"Nope"
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 def bar(self, b, a):
Augie Fackler
py3: port test-batching.py to python3...
r41366 return b"%s und %s" % (b, a,)
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 def greet(self, name=None):
Augie Fackler
py3: port test-batching.py to python3...
r41366 return b"Hello, %s" % name
Gregory Szorc
wireproto: remove iterbatch() from peer interface (API)...
r37651
@contextlib.contextmanager
def commandexecutor(self):
e = localrepo.localcommandexecutor(self)
try:
yield e
finally:
e.close()
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
# usage of "thing" interface
def use(it):
# Direct call to base method shared between client and server.
Augie Fackler
py3: port test-batching.py to python3...
r41366 bprint(it.hello())
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
# Direct calls to proxied methods. They cause individual roundtrips.
Augie Fackler
py3: port test-batching.py to python3...
r41366 bprint(it.foo(b"Un", two=b"Deux"))
bprint(it.bar(b"Eins", b"Zwei"))
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
Gregory Szorc
wireproto: overhaul iterating batcher code (API)...
r33761 # Batched call to a couple of proxied methods.
Gregory Szorc
wireproto: remove iterbatch() from peer interface (API)...
r37651 with it.commandexecutor() as e:
Augie Fackler
py3: port test-batching.py to python3...
r41366 ffoo = e.callcommand(b'foo', {b'one': b'One', b'two': b'Two'})
fbar = e.callcommand(b'bar', {b'b': b'Eins', b'a': b'Zwei'})
fbar2 = e.callcommand(b'bar', {b'b': b'Uno', b'a': b'Due'})
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
Augie Fackler
py3: port test-batching.py to python3...
r41366 bprint(ffoo.result())
bprint(fbar.result())
bprint(fbar2.result())
Gregory Szorc
wireproto: overhaul iterating batcher code (API)...
r33761
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 # local usage
mylocal = localthing()
Robert Stanca
py3: use print_function in test-batching.py
r28732 print()
Augie Fackler
py3: port test-batching.py to python3...
r41366 bprint(b"== Local")
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 use(mylocal)
# demo remoting; mimicks what wireproto and HTTP/SSH do
# shared
def escapearg(plain):
return (plain
Augie Fackler
py3: port test-batching.py to python3...
r41366 .replace(b':', b'::')
.replace(b',', b':,')
.replace(b';', b':;')
.replace(b'=', b':='))
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 def unescapearg(escaped):
return (escaped
Augie Fackler
py3: port test-batching.py to python3...
r41366 .replace(b':=', b'=')
.replace(b':;', b';')
.replace(b':,', b',')
.replace(b'::', b':'))
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
# server side
# equivalent of wireproto's global functions
Thomas Arendsen Hein
classes: fix class style problems found by b071cd58af50...
r14764 class server(object):
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 def __init__(self, local):
self.local = local
def _call(self, name, args):
Augie Fackler
py3: port test-batching.py to python3...
r41366 args = dict(arg.split(b'=', 1) for arg in args)
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 return getattr(self, name)(**args)
def perform(self, req):
Augie Fackler
py3: port test-batching.py to python3...
r41366 bprint(b"REQ:", req)
name, args = req.split(b'?', 1)
args = args.split(b'&')
vals = dict(arg.split(b'=', 1) for arg in args)
res = getattr(self, pycompat.sysstr(name))(**pycompat.strkwargs(vals))
bprint(b" ->", res)
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 return res
def batch(self, cmds):
res = []
Augie Fackler
py3: port test-batching.py to python3...
r41366 for pair in cmds.split(b';'):
name, args = pair.split(b':', 1)
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 vals = {}
Augie Fackler
py3: port test-batching.py to python3...
r41366 for a in args.split(b','):
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 if a:
Augie Fackler
py3: port test-batching.py to python3...
r41366 n, v = a.split(b'=')
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 vals[n] = unescapearg(v)
Augie Fackler
py3: port test-batching.py to python3...
r41366 res.append(escapearg(getattr(self, pycompat.sysstr(name))(
**pycompat.strkwargs(vals))))
return b';'.join(res)
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 def foo(self, one, two):
return mangle(self.local.foo(unmangle(one), unmangle(two)))
def bar(self, b, a):
return mangle(self.local.bar(unmangle(b), unmangle(a)))
def greet(self, name):
return mangle(self.local.greet(unmangle(name)))
myserver = server(mylocal)
# local side
# equivalent of wireproto.encode/decodelist, that is, type-specific marshalling
# here we just transform the strings a bit to check we're properly en-/decoding
def mangle(s):
Augie Fackler
py3: port test-batching.py to python3...
r41366 return b''.join(pycompat.bytechr(ord(c) + 1) for c in pycompat.bytestr(s))
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 def unmangle(s):
Augie Fackler
py3: port test-batching.py to python3...
r41366 return b''.join(pycompat.bytechr(ord(c) - 1) for c in pycompat.bytestr(s))
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
# equivalent of wireproto.wirerepository and something like http's wire format
class remotething(thing):
def __init__(self, server):
self.server = server
def _submitone(self, name, args):
Augie Fackler
py3: port test-batching.py to python3...
r41366 req = name + b'?' + b'&'.join([b'%s=%s' % (n, v) for n, v in args])
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 return self.server.perform(req)
def _submitbatch(self, cmds):
req = []
for name, args in cmds:
Augie Fackler
py3: port test-batching.py to python3...
r41366 args = b','.join(n + b'=' + escapearg(v) for n, v in args)
req.append(name + b':' + args)
req = b';'.join(req)
res = self._submitone(b'batch', [(b'cmds', req,)])
for r in res.split(b';'):
Gregory Szorc
wireproto: overhaul iterating batcher code (API)...
r33761 yield r
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
Gregory Szorc
wireproto: remove iterbatch() from peer interface (API)...
r37651 @contextlib.contextmanager
def commandexecutor(self):
e = wireprotov1peer.peerexecutor(self)
try:
yield e
finally:
e.close()
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
Gregory Szorc
peer: scatter module to the wind (API)...
r37633 @wireprotov1peer.batchable
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 def foo(self, one, two=None):
Augie Fackler
py3: port test-batching.py to python3...
r41366 encargs = [(b'one', mangle(one),), (b'two', mangle(two),)]
Gregory Szorc
peer: scatter module to the wind (API)...
r37633 encresref = wireprotov1peer.future()
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 yield encargs, encresref
yield unmangle(encresref.value)
Gregory Szorc
peer: scatter module to the wind (API)...
r37633 @wireprotov1peer.batchable
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 def bar(self, b, a):
Gregory Szorc
peer: scatter module to the wind (API)...
r37633 encresref = wireprotov1peer.future()
Augie Fackler
py3: port test-batching.py to python3...
r41366 yield [(b'b', mangle(b),), (b'a', mangle(a),)], encresref
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 yield unmangle(encresref.value)
# greet is coded directly. It therefore does not support batching. If it
# does appear in a batch, the batch is split around greet, and the call to
# greet is done in its own roundtrip.
def greet(self, name=None):
Augie Fackler
py3: port test-batching.py to python3...
r41366 return unmangle(self._submitone(b'greet', [(b'name', mangle(name),)]))
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621
# demo remote usage
myproxy = remotething(myserver)
Robert Stanca
py3: use print_function in test-batching.py
r28732 print()
Augie Fackler
py3: port test-batching.py to python3...
r41366 bprint(b"== Remote")
Peter Arrenbrecht
wireproto: add basic command batching infrastructure...
r14621 use(myproxy)