test-wireproto-clientreactor.py
144 lines
| 5.0 KiB
| text/x-python
|
PythonLexer
/ tests / test-wireproto-clientreactor.py
Gregory Szorc
|
r37561 | from __future__ import absolute_import | ||
import unittest | ||||
from mercurial import ( | ||||
error, | ||||
wireprotoframing as framing, | ||||
) | ||||
Gregory Szorc
|
r37562 | ffs = framing.makeframefromhumanstring | ||
def sendframe(reactor, frame): | ||||
"""Send a frame bytearray to a reactor.""" | ||||
header = framing.parseheader(frame) | ||||
payload = frame[framing.FRAME_HEADER_SIZE:] | ||||
assert len(payload) == header.length | ||||
return reactor.onframerecv(framing.frame(header.requestid, | ||||
header.streamid, | ||||
header.streamflags, | ||||
header.typeid, | ||||
header.flags, | ||||
payload)) | ||||
Gregory Szorc
|
r37561 | class SingleSendTests(unittest.TestCase): | ||
"""A reactor that can only send once rejects subsequent sends.""" | ||||
Augie Fackler
|
r37733 | |||
if not getattr(unittest.TestCase, 'assertRaisesRegex', False): | ||||
# Python 3.7 deprecates the regex*p* version, but 2.7 lacks | ||||
# the regex version. | ||||
assertRaisesRegex = (# camelcase-required | ||||
unittest.TestCase.assertRaisesRegexp) | ||||
Gregory Szorc
|
r37561 | def testbasic(self): | ||
reactor = framing.clientreactor(hasmultiplesend=False, buffersends=True) | ||||
request, action, meta = reactor.callcommand(b'foo', {}) | ||||
Augie Fackler
|
r37700 | self.assertEqual(request.state, b'pending') | ||
self.assertEqual(action, b'noop') | ||||
Gregory Szorc
|
r37561 | |||
action, meta = reactor.flushcommands() | ||||
Augie Fackler
|
r37700 | self.assertEqual(action, b'sendframes') | ||
Gregory Szorc
|
r37561 | |||
Augie Fackler
|
r37700 | for frame in meta[b'framegen']: | ||
self.assertEqual(request.state, b'sending') | ||||
Gregory Szorc
|
r37561 | |||
Augie Fackler
|
r37700 | self.assertEqual(request.state, b'sent') | ||
Gregory Szorc
|
r37561 | |||
Augie Fackler
|
r37733 | with self.assertRaisesRegex(error.ProgrammingError, | ||
Gregory Szorc
|
r37561 | 'cannot issue new commands'): | ||
reactor.callcommand(b'foo', {}) | ||||
Augie Fackler
|
r37733 | with self.assertRaisesRegex(error.ProgrammingError, | ||
Gregory Szorc
|
r37561 | 'cannot issue new commands'): | ||
reactor.callcommand(b'foo', {}) | ||||
class NoBufferTests(unittest.TestCase): | ||||
"""A reactor without send buffering sends requests immediately.""" | ||||
def testbasic(self): | ||||
reactor = framing.clientreactor(hasmultiplesend=True, buffersends=False) | ||||
request, action, meta = reactor.callcommand(b'command1', {}) | ||||
self.assertEqual(request.requestid, 1) | ||||
Augie Fackler
|
r37700 | self.assertEqual(action, b'sendframes') | ||
Gregory Szorc
|
r37561 | |||
Augie Fackler
|
r37700 | self.assertEqual(request.state, b'pending') | ||
Gregory Szorc
|
r37561 | |||
Augie Fackler
|
r37700 | for frame in meta[b'framegen']: | ||
self.assertEqual(request.state, b'sending') | ||||
Gregory Szorc
|
r37561 | |||
Augie Fackler
|
r37700 | self.assertEqual(request.state, b'sent') | ||
Gregory Szorc
|
r37561 | |||
action, meta = reactor.flushcommands() | ||||
Augie Fackler
|
r37700 | self.assertEqual(action, b'noop') | ||
Gregory Szorc
|
r37561 | |||
# And we can send another command. | ||||
request, action, meta = reactor.callcommand(b'command2', {}) | ||||
self.assertEqual(request.requestid, 3) | ||||
Augie Fackler
|
r37700 | self.assertEqual(action, b'sendframes') | ||
Gregory Szorc
|
r37561 | |||
Augie Fackler
|
r37700 | for frame in meta[b'framegen']: | ||
self.assertEqual(request.state, b'sending') | ||||
Gregory Szorc
|
r37561 | |||
Augie Fackler
|
r37700 | self.assertEqual(request.state, b'sent') | ||
Gregory Szorc
|
r37561 | |||
Gregory Szorc
|
r37562 | class BadFrameRecvTests(unittest.TestCase): | ||
Augie Fackler
|
r37733 | if not getattr(unittest.TestCase, 'assertRaisesRegex', False): | ||
# Python 3.7 deprecates the regex*p* version, but 2.7 lacks | ||||
# the regex version. | ||||
assertRaisesRegex = (# camelcase-required | ||||
unittest.TestCase.assertRaisesRegexp) | ||||
Gregory Szorc
|
r37562 | def testoddstream(self): | ||
reactor = framing.clientreactor() | ||||
action, meta = sendframe(reactor, ffs(b'1 1 0 1 0 foo')) | ||||
Augie Fackler
|
r37700 | self.assertEqual(action, b'error') | ||
self.assertEqual(meta[b'message'], | ||||
b'received frame with odd numbered stream ID: 1') | ||||
Gregory Szorc
|
r37562 | |||
def testunknownstream(self): | ||||
reactor = framing.clientreactor() | ||||
action, meta = sendframe(reactor, ffs(b'1 0 0 1 0 foo')) | ||||
Augie Fackler
|
r37700 | self.assertEqual(action, b'error') | ||
self.assertEqual(meta[b'message'], | ||||
b'received frame on unknown stream without beginning ' | ||||
b'of stream flag set') | ||||
Gregory Szorc
|
r37562 | |||
def testunhandledframetype(self): | ||||
reactor = framing.clientreactor(buffersends=False) | ||||
request, action, meta = reactor.callcommand(b'foo', {}) | ||||
Augie Fackler
|
r37700 | for frame in meta[b'framegen']: | ||
Gregory Szorc
|
r37562 | pass | ||
Augie Fackler
|
r37733 | with self.assertRaisesRegex(error.ProgrammingError, | ||
Gregory Szorc
|
r37562 | 'unhandled frame type'): | ||
sendframe(reactor, ffs(b'1 0 stream-begin text-output 0 foo')) | ||||
Gregory Szorc
|
r37674 | class StreamTests(unittest.TestCase): | ||
def testmultipleresponseframes(self): | ||||
reactor = framing.clientreactor(buffersends=False) | ||||
request, action, meta = reactor.callcommand(b'foo', {}) | ||||
Augie Fackler
|
r37700 | self.assertEqual(action, b'sendframes') | ||
for f in meta[b'framegen']: | ||||
Gregory Szorc
|
r37674 | pass | ||
action, meta = sendframe( | ||||
reactor, | ||||
Gregory Szorc
|
r37742 | ffs(b'%d 0 stream-begin command-response 0 foo' % | ||
request.requestid)) | ||||
Augie Fackler
|
r37700 | self.assertEqual(action, b'responsedata') | ||
Gregory Szorc
|
r37674 | |||
action, meta = sendframe( | ||||
reactor, | ||||
Gregory Szorc
|
r37742 | ffs(b'%d 0 0 command-response eos bar' % request.requestid)) | ||
Augie Fackler
|
r37700 | self.assertEqual(action, b'responsedata') | ||
Gregory Szorc
|
r37674 | |||
Gregory Szorc
|
r37561 | if __name__ == '__main__': | ||
import silenttestrunner | ||||
silenttestrunner.main(__name__) | ||||