Both of these tests now pass on Python 3.
- skip-blame just b prefixes. So many b prefixes.
pulkit |
hg-reviewers |
Both of these tests now pass on Python 3.
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
Path | Packages | |||
---|---|---|---|---|
M | contrib/python3-whitelist (2 lines) | |||
M | tests/test-wireproto-clientreactor.py (56 lines) | |||
M | tests/test-wireproto-serverreactor.py (204 lines) |
test-update-names.t | test-update-names.t | ||||
test-update-reverse.t | test-update-reverse.t | ||||
test-upgrade-repo.t | test-upgrade-repo.t | ||||
test-url-rev.t | test-url-rev.t | ||||
test-username-newline.t | test-username-newline.t | ||||
test-verify.t | test-verify.t | ||||
test-websub.t | test-websub.t | ||||
test-win32text.t | test-win32text.t | ||||
test-wireproto-clientreactor.py | |||||
test-wireproto-framing.py | test-wireproto-framing.py | ||||
test-wireproto-serverreactor.py | |||||
test-xdg.t | test-xdg.t |
payload)) | payload)) | ||||
class SingleSendTests(unittest.TestCase): | class SingleSendTests(unittest.TestCase): | ||||
"""A reactor that can only send once rejects subsequent sends.""" | """A reactor that can only send once rejects subsequent sends.""" | ||||
def testbasic(self): | def testbasic(self): | ||||
reactor = framing.clientreactor(hasmultiplesend=False, buffersends=True) | reactor = framing.clientreactor(hasmultiplesend=False, buffersends=True) | ||||
request, action, meta = reactor.callcommand(b'foo', {}) | request, action, meta = reactor.callcommand(b'foo', {}) | ||||
self.assertEqual(request.state, 'pending') | self.assertEqual(request.state, b'pending') | ||||
self.assertEqual(action, 'noop') | self.assertEqual(action, b'noop') | ||||
action, meta = reactor.flushcommands() | action, meta = reactor.flushcommands() | ||||
self.assertEqual(action, 'sendframes') | self.assertEqual(action, b'sendframes') | ||||
for frame in meta['framegen']: | for frame in meta[b'framegen']: | ||||
self.assertEqual(request.state, 'sending') | self.assertEqual(request.state, b'sending') | ||||
self.assertEqual(request.state, 'sent') | self.assertEqual(request.state, b'sent') | ||||
with self.assertRaisesRegexp(error.ProgrammingError, | with self.assertRaisesRegexp(error.ProgrammingError, | ||||
'cannot issue new commands'): | 'cannot issue new commands'): | ||||
reactor.callcommand(b'foo', {}) | reactor.callcommand(b'foo', {}) | ||||
with self.assertRaisesRegexp(error.ProgrammingError, | with self.assertRaisesRegexp(error.ProgrammingError, | ||||
'cannot issue new commands'): | 'cannot issue new commands'): | ||||
reactor.callcommand(b'foo', {}) | reactor.callcommand(b'foo', {}) | ||||
class NoBufferTests(unittest.TestCase): | class NoBufferTests(unittest.TestCase): | ||||
"""A reactor without send buffering sends requests immediately.""" | """A reactor without send buffering sends requests immediately.""" | ||||
def testbasic(self): | def testbasic(self): | ||||
reactor = framing.clientreactor(hasmultiplesend=True, buffersends=False) | reactor = framing.clientreactor(hasmultiplesend=True, buffersends=False) | ||||
request, action, meta = reactor.callcommand(b'command1', {}) | request, action, meta = reactor.callcommand(b'command1', {}) | ||||
self.assertEqual(request.requestid, 1) | self.assertEqual(request.requestid, 1) | ||||
self.assertEqual(action, 'sendframes') | self.assertEqual(action, b'sendframes') | ||||
self.assertEqual(request.state, 'pending') | self.assertEqual(request.state, b'pending') | ||||
for frame in meta['framegen']: | for frame in meta[b'framegen']: | ||||
self.assertEqual(request.state, 'sending') | self.assertEqual(request.state, b'sending') | ||||
self.assertEqual(request.state, 'sent') | self.assertEqual(request.state, b'sent') | ||||
action, meta = reactor.flushcommands() | action, meta = reactor.flushcommands() | ||||
self.assertEqual(action, 'noop') | self.assertEqual(action, b'noop') | ||||
# And we can send another command. | # And we can send another command. | ||||
request, action, meta = reactor.callcommand(b'command2', {}) | request, action, meta = reactor.callcommand(b'command2', {}) | ||||
self.assertEqual(request.requestid, 3) | self.assertEqual(request.requestid, 3) | ||||
self.assertEqual(action, 'sendframes') | self.assertEqual(action, b'sendframes') | ||||
for frame in meta['framegen']: | for frame in meta[b'framegen']: | ||||
self.assertEqual(request.state, 'sending') | self.assertEqual(request.state, b'sending') | ||||
self.assertEqual(request.state, 'sent') | self.assertEqual(request.state, b'sent') | ||||
class BadFrameRecvTests(unittest.TestCase): | class BadFrameRecvTests(unittest.TestCase): | ||||
def testoddstream(self): | def testoddstream(self): | ||||
reactor = framing.clientreactor() | reactor = framing.clientreactor() | ||||
action, meta = sendframe(reactor, ffs(b'1 1 0 1 0 foo')) | action, meta = sendframe(reactor, ffs(b'1 1 0 1 0 foo')) | ||||
self.assertEqual(action, 'error') | self.assertEqual(action, b'error') | ||||
self.assertEqual(meta['message'], | self.assertEqual(meta[b'message'], | ||||
'received frame with odd numbered stream ID: 1') | b'received frame with odd numbered stream ID: 1') | ||||
def testunknownstream(self): | def testunknownstream(self): | ||||
reactor = framing.clientreactor() | reactor = framing.clientreactor() | ||||
action, meta = sendframe(reactor, ffs(b'1 0 0 1 0 foo')) | action, meta = sendframe(reactor, ffs(b'1 0 0 1 0 foo')) | ||||
self.assertEqual(action, 'error') | self.assertEqual(action, b'error') | ||||
self.assertEqual(meta['message'], | self.assertEqual(meta[b'message'], | ||||
'received frame on unknown stream without beginning ' | b'received frame on unknown stream without beginning ' | ||||
'of stream flag set') | b'of stream flag set') | ||||
def testunhandledframetype(self): | def testunhandledframetype(self): | ||||
reactor = framing.clientreactor(buffersends=False) | reactor = framing.clientreactor(buffersends=False) | ||||
request, action, meta = reactor.callcommand(b'foo', {}) | request, action, meta = reactor.callcommand(b'foo', {}) | ||||
for frame in meta['framegen']: | for frame in meta[b'framegen']: | ||||
pass | pass | ||||
with self.assertRaisesRegexp(error.ProgrammingError, | with self.assertRaisesRegexp(error.ProgrammingError, | ||||
'unhandled frame type'): | 'unhandled frame type'): | ||||
sendframe(reactor, ffs(b'1 0 stream-begin text-output 0 foo')) | sendframe(reactor, ffs(b'1 0 stream-begin text-output 0 foo')) | ||||
class StreamTests(unittest.TestCase): | class StreamTests(unittest.TestCase): | ||||
def testmultipleresponseframes(self): | def testmultipleresponseframes(self): | ||||
reactor = framing.clientreactor(buffersends=False) | reactor = framing.clientreactor(buffersends=False) | ||||
request, action, meta = reactor.callcommand(b'foo', {}) | request, action, meta = reactor.callcommand(b'foo', {}) | ||||
self.assertEqual(action, 'sendframes') | self.assertEqual(action, b'sendframes') | ||||
for f in meta['framegen']: | for f in meta[b'framegen']: | ||||
pass | pass | ||||
action, meta = sendframe( | action, meta = sendframe( | ||||
reactor, | reactor, | ||||
ffs(b'%d 0 stream-begin 4 0 foo' % request.requestid)) | ffs(b'%d 0 stream-begin 4 0 foo' % request.requestid)) | ||||
self.assertEqual(action, 'responsedata') | self.assertEqual(action, b'responsedata') | ||||
action, meta = sendframe( | action, meta = sendframe( | ||||
reactor, | reactor, | ||||
ffs(b'%d 0 0 4 eos bar' % request.requestid)) | ffs(b'%d 0 0 4 eos bar' % request.requestid)) | ||||
self.assertEqual(action, 'responsedata') | self.assertEqual(action, b'responsedata') | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
import silenttestrunner | import silenttestrunner | ||||
silenttestrunner.main(__name__) | silenttestrunner.main(__name__) |
self.assertEqual(list(frames), expected) | self.assertEqual(list(frames), expected) | ||||
def test1framecommand(self): | def test1framecommand(self): | ||||
"""Receiving a command in a single frame yields request to run it.""" | """Receiving a command in a single frame yields request to run it.""" | ||||
reactor = makereactor() | reactor = makereactor() | ||||
stream = framing.stream(1) | stream = framing.stream(1) | ||||
results = list(sendcommandframes(reactor, stream, 1, b'mycommand', {})) | results = list(sendcommandframes(reactor, stream, 1, b'mycommand', {})) | ||||
self.assertEqual(len(results), 1) | self.assertEqual(len(results), 1) | ||||
self.assertaction(results[0], 'runcommand') | self.assertaction(results[0], b'runcommand') | ||||
self.assertEqual(results[0][1], { | self.assertEqual(results[0][1], { | ||||
'requestid': 1, | b'requestid': 1, | ||||
'command': b'mycommand', | b'command': b'mycommand', | ||||
'args': {}, | b'args': {}, | ||||
'data': None, | b'data': None, | ||||
}) | }) | ||||
result = reactor.oninputeof() | result = reactor.oninputeof() | ||||
self.assertaction(result, 'noop') | self.assertaction(result, b'noop') | ||||
def test1argument(self): | def test1argument(self): | ||||
reactor = makereactor() | reactor = makereactor() | ||||
stream = framing.stream(1) | stream = framing.stream(1) | ||||
results = list(sendcommandframes(reactor, stream, 41, b'mycommand', | results = list(sendcommandframes(reactor, stream, 41, b'mycommand', | ||||
{b'foo': b'bar'})) | {b'foo': b'bar'})) | ||||
self.assertEqual(len(results), 1) | self.assertEqual(len(results), 1) | ||||
self.assertaction(results[0], 'runcommand') | self.assertaction(results[0], b'runcommand') | ||||
self.assertEqual(results[0][1], { | self.assertEqual(results[0][1], { | ||||
'requestid': 41, | b'requestid': 41, | ||||
'command': b'mycommand', | b'command': b'mycommand', | ||||
'args': {b'foo': b'bar'}, | b'args': {b'foo': b'bar'}, | ||||
'data': None, | b'data': None, | ||||
}) | }) | ||||
def testmultiarguments(self): | def testmultiarguments(self): | ||||
reactor = makereactor() | reactor = makereactor() | ||||
stream = framing.stream(1) | stream = framing.stream(1) | ||||
results = list(sendcommandframes(reactor, stream, 1, b'mycommand', | results = list(sendcommandframes(reactor, stream, 1, b'mycommand', | ||||
{b'foo': b'bar', b'biz': b'baz'})) | {b'foo': b'bar', b'biz': b'baz'})) | ||||
self.assertEqual(len(results), 1) | self.assertEqual(len(results), 1) | ||||
self.assertaction(results[0], 'runcommand') | self.assertaction(results[0], b'runcommand') | ||||
self.assertEqual(results[0][1], { | self.assertEqual(results[0][1], { | ||||
'requestid': 1, | b'requestid': 1, | ||||
'command': b'mycommand', | b'command': b'mycommand', | ||||
'args': {b'foo': b'bar', b'biz': b'baz'}, | b'args': {b'foo': b'bar', b'biz': b'baz'}, | ||||
'data': None, | b'data': None, | ||||
}) | }) | ||||
def testsimplecommanddata(self): | def testsimplecommanddata(self): | ||||
reactor = makereactor() | reactor = makereactor() | ||||
stream = framing.stream(1) | stream = framing.stream(1) | ||||
results = list(sendcommandframes(reactor, stream, 1, b'mycommand', {}, | results = list(sendcommandframes(reactor, stream, 1, b'mycommand', {}, | ||||
util.bytesio(b'data!'))) | util.bytesio(b'data!'))) | ||||
self.assertEqual(len(results), 2) | self.assertEqual(len(results), 2) | ||||
self.assertaction(results[0], 'wantframe') | self.assertaction(results[0], b'wantframe') | ||||
self.assertaction(results[1], 'runcommand') | self.assertaction(results[1], b'runcommand') | ||||
self.assertEqual(results[1][1], { | self.assertEqual(results[1][1], { | ||||
'requestid': 1, | b'requestid': 1, | ||||
'command': b'mycommand', | b'command': b'mycommand', | ||||
'args': {}, | b'args': {}, | ||||
'data': b'data!', | b'data': b'data!', | ||||
}) | }) | ||||
def testmultipledataframes(self): | def testmultipledataframes(self): | ||||
frames = [ | frames = [ | ||||
ffs(b'1 1 stream-begin command-request new|have-data ' | ffs(b'1 1 stream-begin command-request new|have-data ' | ||||
b"cbor:{b'name': b'mycommand'}"), | b"cbor:{b'name': b'mycommand'}"), | ||||
ffs(b'1 1 0 command-data continuation data1'), | ffs(b'1 1 0 command-data continuation data1'), | ||||
ffs(b'1 1 0 command-data continuation data2'), | ffs(b'1 1 0 command-data continuation data2'), | ||||
ffs(b'1 1 0 command-data eos data3'), | ffs(b'1 1 0 command-data eos data3'), | ||||
] | ] | ||||
reactor = makereactor() | reactor = makereactor() | ||||
results = list(sendframes(reactor, frames)) | results = list(sendframes(reactor, frames)) | ||||
self.assertEqual(len(results), 4) | self.assertEqual(len(results), 4) | ||||
for i in range(3): | for i in range(3): | ||||
self.assertaction(results[i], 'wantframe') | self.assertaction(results[i], b'wantframe') | ||||
self.assertaction(results[3], 'runcommand') | self.assertaction(results[3], b'runcommand') | ||||
self.assertEqual(results[3][1], { | self.assertEqual(results[3][1], { | ||||
'requestid': 1, | b'requestid': 1, | ||||
'command': b'mycommand', | b'command': b'mycommand', | ||||
'args': {}, | b'args': {}, | ||||
'data': b'data1data2data3', | b'data': b'data1data2data3', | ||||
}) | }) | ||||
def testargumentanddata(self): | def testargumentanddata(self): | ||||
frames = [ | frames = [ | ||||
ffs(b'1 1 stream-begin command-request new|have-data ' | ffs(b'1 1 stream-begin command-request new|have-data ' | ||||
b"cbor:{b'name': b'command', b'args': {b'key': b'val'," | b"cbor:{b'name': b'command', b'args': {b'key': b'val'," | ||||
b"b'foo': b'bar'}}"), | b"b'foo': b'bar'}}"), | ||||
ffs(b'1 1 0 command-data continuation value1'), | ffs(b'1 1 0 command-data continuation value1'), | ||||
ffs(b'1 1 0 command-data eos value2'), | ffs(b'1 1 0 command-data eos value2'), | ||||
] | ] | ||||
reactor = makereactor() | reactor = makereactor() | ||||
results = list(sendframes(reactor, frames)) | results = list(sendframes(reactor, frames)) | ||||
self.assertaction(results[-1], 'runcommand') | self.assertaction(results[-1], b'runcommand') | ||||
self.assertEqual(results[-1][1], { | self.assertEqual(results[-1][1], { | ||||
'requestid': 1, | b'requestid': 1, | ||||
'command': b'command', | b'command': b'command', | ||||
'args': { | b'args': { | ||||
b'key': b'val', | b'key': b'val', | ||||
b'foo': b'bar', | b'foo': b'bar', | ||||
}, | }, | ||||
'data': b'value1value2', | b'data': b'value1value2', | ||||
}) | }) | ||||
def testnewandcontinuation(self): | def testnewandcontinuation(self): | ||||
result = self._sendsingleframe(makereactor(), | result = self._sendsingleframe(makereactor(), | ||||
ffs(b'1 1 stream-begin command-request new|continuation ')) | ffs(b'1 1 stream-begin command-request new|continuation ')) | ||||
self.assertaction(result, 'error') | self.assertaction(result, b'error') | ||||
self.assertEqual(result[1], { | self.assertEqual(result[1], { | ||||
'message': b'received command request frame with both new and ' | b'message': b'received command request frame with both new and ' | ||||
b'continuation flags set', | b'continuation flags set', | ||||
}) | }) | ||||
def testneithernewnorcontinuation(self): | def testneithernewnorcontinuation(self): | ||||
result = self._sendsingleframe(makereactor(), | result = self._sendsingleframe(makereactor(), | ||||
ffs(b'1 1 stream-begin command-request 0 ')) | ffs(b'1 1 stream-begin command-request 0 ')) | ||||
self.assertaction(result, 'error') | self.assertaction(result, b'error') | ||||
self.assertEqual(result[1], { | self.assertEqual(result[1], { | ||||
'message': b'received command request frame with neither new nor ' | b'message': b'received command request frame with neither new nor ' | ||||
b'continuation flags set', | b'continuation flags set', | ||||
}) | }) | ||||
def testunexpectedcommanddata(self): | def testunexpectedcommanddata(self): | ||||
"""Command data frame when not running a command is an error.""" | """Command data frame when not running a command is an error.""" | ||||
result = self._sendsingleframe(makereactor(), | result = self._sendsingleframe(makereactor(), | ||||
ffs(b'1 1 stream-begin command-data 0 ignored')) | ffs(b'1 1 stream-begin command-data 0 ignored')) | ||||
self.assertaction(result, 'error') | self.assertaction(result, b'error') | ||||
self.assertEqual(result[1], { | self.assertEqual(result[1], { | ||||
'message': b'expected command request frame; got 3', | b'message': b'expected command request frame; got 3', | ||||
}) | }) | ||||
def testunexpectedcommanddatareceiving(self): | def testunexpectedcommanddatareceiving(self): | ||||
"""Same as above except the command is receiving.""" | """Same as above except the command is receiving.""" | ||||
results = list(sendframes(makereactor(), [ | results = list(sendframes(makereactor(), [ | ||||
ffs(b'1 1 stream-begin command-request new|more ' | ffs(b'1 1 stream-begin command-request new|more ' | ||||
b"cbor:{b'name': b'ignored'}"), | b"cbor:{b'name': b'ignored'}"), | ||||
ffs(b'1 1 0 command-data eos ignored'), | ffs(b'1 1 0 command-data eos ignored'), | ||||
])) | ])) | ||||
self.assertaction(results[0], 'wantframe') | self.assertaction(results[0], b'wantframe') | ||||
self.assertaction(results[1], 'error') | self.assertaction(results[1], b'error') | ||||
self.assertEqual(results[1][1], { | self.assertEqual(results[1][1], { | ||||
'message': b'received command data frame for request that is not ' | b'message': b'received command data frame for request that is not ' | ||||
b'expecting data: 1', | b'expecting data: 1', | ||||
}) | }) | ||||
def testconflictingrequestidallowed(self): | def testconflictingrequestidallowed(self): | ||||
"""Multiple fully serviced commands with same request ID is allowed.""" | """Multiple fully serviced commands with same request ID is allowed.""" | ||||
reactor = makereactor() | reactor = makereactor() | ||||
results = [] | results = [] | ||||
outstream = reactor.makeoutputstream() | outstream = reactor.makeoutputstream() | ||||
results.append(self._sendsingleframe( | results.append(self._sendsingleframe( | ||||
reactor, ffs(b'1 1 stream-begin command-request new ' | reactor, ffs(b'1 1 stream-begin command-request new ' | ||||
b"cbor:{b'name': b'command'}"))) | b"cbor:{b'name': b'command'}"))) | ||||
result = reactor.onbytesresponseready(outstream, 1, b'response1') | result = reactor.onbytesresponseready(outstream, 1, b'response1') | ||||
self.assertaction(result, 'sendframes') | self.assertaction(result, b'sendframes') | ||||
list(result[1]['framegen']) | list(result[1][b'framegen']) | ||||
results.append(self._sendsingleframe( | results.append(self._sendsingleframe( | ||||
reactor, ffs(b'1 1 stream-begin command-request new ' | reactor, ffs(b'1 1 stream-begin command-request new ' | ||||
b"cbor:{b'name': b'command'}"))) | b"cbor:{b'name': b'command'}"))) | ||||
result = reactor.onbytesresponseready(outstream, 1, b'response2') | result = reactor.onbytesresponseready(outstream, 1, b'response2') | ||||
self.assertaction(result, 'sendframes') | self.assertaction(result, b'sendframes') | ||||
list(result[1]['framegen']) | list(result[1][b'framegen']) | ||||
results.append(self._sendsingleframe( | results.append(self._sendsingleframe( | ||||
reactor, ffs(b'1 1 stream-begin command-request new ' | reactor, ffs(b'1 1 stream-begin command-request new ' | ||||
b"cbor:{b'name': b'command'}"))) | b"cbor:{b'name': b'command'}"))) | ||||
result = reactor.onbytesresponseready(outstream, 1, b'response3') | result = reactor.onbytesresponseready(outstream, 1, b'response3') | ||||
self.assertaction(result, 'sendframes') | self.assertaction(result, b'sendframes') | ||||
list(result[1]['framegen']) | list(result[1][b'framegen']) | ||||
for i in range(3): | for i in range(3): | ||||
self.assertaction(results[i], 'runcommand') | self.assertaction(results[i], b'runcommand') | ||||
self.assertEqual(results[i][1], { | self.assertEqual(results[i][1], { | ||||
'requestid': 1, | b'requestid': 1, | ||||
'command': b'command', | b'command': b'command', | ||||
'args': {}, | b'args': {}, | ||||
'data': None, | b'data': None, | ||||
}) | }) | ||||
def testconflictingrequestid(self): | def testconflictingrequestid(self): | ||||
"""Request ID for new command matching in-flight command is illegal.""" | """Request ID for new command matching in-flight command is illegal.""" | ||||
results = list(sendframes(makereactor(), [ | results = list(sendframes(makereactor(), [ | ||||
ffs(b'1 1 stream-begin command-request new|more ' | ffs(b'1 1 stream-begin command-request new|more ' | ||||
b"cbor:{b'name': b'command'}"), | b"cbor:{b'name': b'command'}"), | ||||
ffs(b'1 1 0 command-request new ' | ffs(b'1 1 0 command-request new ' | ||||
b"cbor:{b'name': b'command1'}"), | b"cbor:{b'name': b'command1'}"), | ||||
])) | ])) | ||||
self.assertaction(results[0], 'wantframe') | self.assertaction(results[0], b'wantframe') | ||||
self.assertaction(results[1], 'error') | self.assertaction(results[1], b'error') | ||||
self.assertEqual(results[1][1], { | self.assertEqual(results[1][1], { | ||||
'message': b'request with ID 1 already received', | b'message': b'request with ID 1 already received', | ||||
}) | }) | ||||
def testinterleavedcommands(self): | def testinterleavedcommands(self): | ||||
cbor1 = cbor.dumps({ | cbor1 = cbor.dumps({ | ||||
b'name': b'command1', | b'name': b'command1', | ||||
b'args': { | b'args': { | ||||
b'foo': b'bar', | b'foo': b'bar', | ||||
b'key1': b'val', | b'key1': b'val', | ||||
ffs(b'3 1 0 command-request new|more %s' % cbor3[0:10]), | ffs(b'3 1 0 command-request new|more %s' % cbor3[0:10]), | ||||
ffs(b'1 1 0 command-request continuation|more %s' % cbor1[6:9]), | ffs(b'1 1 0 command-request continuation|more %s' % cbor1[6:9]), | ||||
ffs(b'3 1 0 command-request continuation|more %s' % cbor3[10:13]), | ffs(b'3 1 0 command-request continuation|more %s' % cbor3[10:13]), | ||||
ffs(b'3 1 0 command-request continuation %s' % cbor3[13:]), | ffs(b'3 1 0 command-request continuation %s' % cbor3[13:]), | ||||
ffs(b'1 1 0 command-request continuation %s' % cbor1[9:]), | ffs(b'1 1 0 command-request continuation %s' % cbor1[9:]), | ||||
])) | ])) | ||||
self.assertEqual([t[0] for t in results], [ | self.assertEqual([t[0] for t in results], [ | ||||
'wantframe', | b'wantframe', | ||||
'wantframe', | b'wantframe', | ||||
'wantframe', | b'wantframe', | ||||
'wantframe', | b'wantframe', | ||||
'runcommand', | b'runcommand', | ||||
'runcommand', | b'runcommand', | ||||
]) | ]) | ||||
self.assertEqual(results[4][1], { | self.assertEqual(results[4][1], { | ||||
'requestid': 3, | b'requestid': 3, | ||||
'command': 'command3', | b'command': b'command3', | ||||
'args': {b'biz': b'baz', b'key': b'val'}, | b'args': {b'biz': b'baz', b'key': b'val'}, | ||||
'data': None, | b'data': None, | ||||
}) | }) | ||||
self.assertEqual(results[5][1], { | self.assertEqual(results[5][1], { | ||||
'requestid': 1, | b'requestid': 1, | ||||
'command': 'command1', | b'command': b'command1', | ||||
'args': {b'foo': b'bar', b'key1': b'val'}, | b'args': {b'foo': b'bar', b'key1': b'val'}, | ||||
'data': None, | b'data': None, | ||||
}) | }) | ||||
def testmissingcommanddataframe(self): | def testmissingcommanddataframe(self): | ||||
# The reactor doesn't currently handle partially received commands. | # The reactor doesn't currently handle partially received commands. | ||||
# So this test is failing to do anything with request 1. | # So this test is failing to do anything with request 1. | ||||
frames = [ | frames = [ | ||||
ffs(b'1 1 stream-begin command-request new|have-data ' | ffs(b'1 1 stream-begin command-request new|have-data ' | ||||
b"cbor:{b'name': b'command1'}"), | b"cbor:{b'name': b'command1'}"), | ||||
ffs(b'3 1 0 command-request new ' | ffs(b'3 1 0 command-request new ' | ||||
b"cbor:{b'name': b'command2'}"), | b"cbor:{b'name': b'command2'}"), | ||||
] | ] | ||||
results = list(sendframes(makereactor(), frames)) | results = list(sendframes(makereactor(), frames)) | ||||
self.assertEqual(len(results), 2) | self.assertEqual(len(results), 2) | ||||
self.assertaction(results[0], 'wantframe') | self.assertaction(results[0], b'wantframe') | ||||
self.assertaction(results[1], 'runcommand') | self.assertaction(results[1], b'runcommand') | ||||
def testmissingcommanddataframeflags(self): | def testmissingcommanddataframeflags(self): | ||||
frames = [ | frames = [ | ||||
ffs(b'1 1 stream-begin command-request new|have-data ' | ffs(b'1 1 stream-begin command-request new|have-data ' | ||||
b"cbor:{b'name': b'command1'}"), | b"cbor:{b'name': b'command1'}"), | ||||
ffs(b'1 1 0 command-data 0 data'), | ffs(b'1 1 0 command-data 0 data'), | ||||
] | ] | ||||
results = list(sendframes(makereactor(), frames)) | results = list(sendframes(makereactor(), frames)) | ||||
self.assertEqual(len(results), 2) | self.assertEqual(len(results), 2) | ||||
self.assertaction(results[0], 'wantframe') | self.assertaction(results[0], b'wantframe') | ||||
self.assertaction(results[1], 'error') | self.assertaction(results[1], b'error') | ||||
self.assertEqual(results[1][1], { | self.assertEqual(results[1][1], { | ||||
'message': b'command data frame without flags', | b'message': b'command data frame without flags', | ||||
}) | }) | ||||
def testframefornonreceivingrequest(self): | def testframefornonreceivingrequest(self): | ||||
"""Receiving a frame for a command that is not receiving is illegal.""" | """Receiving a frame for a command that is not receiving is illegal.""" | ||||
results = list(sendframes(makereactor(), [ | results = list(sendframes(makereactor(), [ | ||||
ffs(b'1 1 stream-begin command-request new ' | ffs(b'1 1 stream-begin command-request new ' | ||||
b"cbor:{b'name': b'command1'}"), | b"cbor:{b'name': b'command1'}"), | ||||
ffs(b'3 1 0 command-request new|have-data ' | ffs(b'3 1 0 command-request new|have-data ' | ||||
b"cbor:{b'name': b'command3'}"), | b"cbor:{b'name': b'command3'}"), | ||||
ffs(b'5 1 0 command-data eos ignored'), | ffs(b'5 1 0 command-data eos ignored'), | ||||
])) | ])) | ||||
self.assertaction(results[2], 'error') | self.assertaction(results[2], b'error') | ||||
self.assertEqual(results[2][1], { | self.assertEqual(results[2][1], { | ||||
'message': b'received frame for request that is not receiving: 5', | b'message': b'received frame for request that is not receiving: 5', | ||||
}) | }) | ||||
def testsimpleresponse(self): | def testsimpleresponse(self): | ||||
"""Bytes response to command sends result frames.""" | """Bytes response to command sends result frames.""" | ||||
reactor = makereactor() | reactor = makereactor() | ||||
instream = framing.stream(1) | instream = framing.stream(1) | ||||
list(sendcommandframes(reactor, instream, 1, b'mycommand', {})) | list(sendcommandframes(reactor, instream, 1, b'mycommand', {})) | ||||
outstream = reactor.makeoutputstream() | outstream = reactor.makeoutputstream() | ||||
result = reactor.onbytesresponseready(outstream, 1, b'response') | result = reactor.onbytesresponseready(outstream, 1, b'response') | ||||
self.assertaction(result, 'sendframes') | self.assertaction(result, b'sendframes') | ||||
self.assertframesequal(result[1]['framegen'], [ | self.assertframesequal(result[1][b'framegen'], [ | ||||
b'1 2 stream-begin bytes-response eos response', | b'1 2 stream-begin bytes-response eos response', | ||||
]) | ]) | ||||
def testmultiframeresponse(self): | def testmultiframeresponse(self): | ||||
"""Bytes response spanning multiple frames is handled.""" | """Bytes response spanning multiple frames is handled.""" | ||||
first = b'x' * framing.DEFAULT_MAX_FRAME_SIZE | first = b'x' * framing.DEFAULT_MAX_FRAME_SIZE | ||||
second = b'y' * 100 | second = b'y' * 100 | ||||
reactor = makereactor() | reactor = makereactor() | ||||
instream = framing.stream(1) | instream = framing.stream(1) | ||||
list(sendcommandframes(reactor, instream, 1, b'mycommand', {})) | list(sendcommandframes(reactor, instream, 1, b'mycommand', {})) | ||||
outstream = reactor.makeoutputstream() | outstream = reactor.makeoutputstream() | ||||
result = reactor.onbytesresponseready(outstream, 1, first + second) | result = reactor.onbytesresponseready(outstream, 1, first + second) | ||||
self.assertaction(result, 'sendframes') | self.assertaction(result, b'sendframes') | ||||
self.assertframesequal(result[1]['framegen'], [ | self.assertframesequal(result[1][b'framegen'], [ | ||||
b'1 2 stream-begin bytes-response continuation %s' % first, | b'1 2 stream-begin bytes-response continuation %s' % first, | ||||
b'1 2 0 bytes-response eos %s' % second, | b'1 2 0 bytes-response eos %s' % second, | ||||
]) | ]) | ||||
def testapplicationerror(self): | def testapplicationerror(self): | ||||
reactor = makereactor() | reactor = makereactor() | ||||
instream = framing.stream(1) | instream = framing.stream(1) | ||||
list(sendcommandframes(reactor, instream, 1, b'mycommand', {})) | list(sendcommandframes(reactor, instream, 1, b'mycommand', {})) | ||||
outstream = reactor.makeoutputstream() | outstream = reactor.makeoutputstream() | ||||
result = reactor.onapplicationerror(outstream, 1, b'some message') | result = reactor.onapplicationerror(outstream, 1, b'some message') | ||||
self.assertaction(result, 'sendframes') | self.assertaction(result, b'sendframes') | ||||
self.assertframesequal(result[1]['framegen'], [ | self.assertframesequal(result[1][b'framegen'], [ | ||||
b'1 2 stream-begin error-response application some message', | b'1 2 stream-begin error-response application some message', | ||||
]) | ]) | ||||
def test1commanddeferresponse(self): | def test1commanddeferresponse(self): | ||||
"""Responses when in deferred output mode are delayed until EOF.""" | """Responses when in deferred output mode are delayed until EOF.""" | ||||
reactor = makereactor(deferoutput=True) | reactor = makereactor(deferoutput=True) | ||||
instream = framing.stream(1) | instream = framing.stream(1) | ||||
results = list(sendcommandframes(reactor, instream, 1, b'mycommand', | results = list(sendcommandframes(reactor, instream, 1, b'mycommand', | ||||
{})) | {})) | ||||
self.assertEqual(len(results), 1) | self.assertEqual(len(results), 1) | ||||
self.assertaction(results[0], 'runcommand') | self.assertaction(results[0], b'runcommand') | ||||
outstream = reactor.makeoutputstream() | outstream = reactor.makeoutputstream() | ||||
result = reactor.onbytesresponseready(outstream, 1, b'response') | result = reactor.onbytesresponseready(outstream, 1, b'response') | ||||
self.assertaction(result, 'noop') | self.assertaction(result, b'noop') | ||||
result = reactor.oninputeof() | result = reactor.oninputeof() | ||||
self.assertaction(result, 'sendframes') | self.assertaction(result, b'sendframes') | ||||
self.assertframesequal(result[1]['framegen'], [ | self.assertframesequal(result[1][b'framegen'], [ | ||||
b'1 2 stream-begin bytes-response eos response', | b'1 2 stream-begin bytes-response eos response', | ||||
]) | ]) | ||||
def testmultiplecommanddeferresponse(self): | def testmultiplecommanddeferresponse(self): | ||||
reactor = makereactor(deferoutput=True) | reactor = makereactor(deferoutput=True) | ||||
instream = framing.stream(1) | instream = framing.stream(1) | ||||
list(sendcommandframes(reactor, instream, 1, b'command1', {})) | list(sendcommandframes(reactor, instream, 1, b'command1', {})) | ||||
list(sendcommandframes(reactor, instream, 3, b'command2', {})) | list(sendcommandframes(reactor, instream, 3, b'command2', {})) | ||||
outstream = reactor.makeoutputstream() | outstream = reactor.makeoutputstream() | ||||
result = reactor.onbytesresponseready(outstream, 1, b'response1') | result = reactor.onbytesresponseready(outstream, 1, b'response1') | ||||
self.assertaction(result, 'noop') | self.assertaction(result, b'noop') | ||||
result = reactor.onbytesresponseready(outstream, 3, b'response2') | result = reactor.onbytesresponseready(outstream, 3, b'response2') | ||||
self.assertaction(result, 'noop') | self.assertaction(result, b'noop') | ||||
result = reactor.oninputeof() | result = reactor.oninputeof() | ||||
self.assertaction(result, 'sendframes') | self.assertaction(result, b'sendframes') | ||||
self.assertframesequal(result[1]['framegen'], [ | self.assertframesequal(result[1][b'framegen'], [ | ||||
b'1 2 stream-begin bytes-response eos response1', | b'1 2 stream-begin bytes-response eos response1', | ||||
b'3 2 0 bytes-response eos response2' | b'3 2 0 bytes-response eos response2' | ||||
]) | ]) | ||||
def testrequestidtracking(self): | def testrequestidtracking(self): | ||||
reactor = makereactor(deferoutput=True) | reactor = makereactor(deferoutput=True) | ||||
instream = framing.stream(1) | instream = framing.stream(1) | ||||
list(sendcommandframes(reactor, instream, 1, b'command1', {})) | list(sendcommandframes(reactor, instream, 1, b'command1', {})) | ||||
list(sendcommandframes(reactor, instream, 3, b'command2', {})) | list(sendcommandframes(reactor, instream, 3, b'command2', {})) | ||||
list(sendcommandframes(reactor, instream, 5, b'command3', {})) | list(sendcommandframes(reactor, instream, 5, b'command3', {})) | ||||
# Register results for commands out of order. | # Register results for commands out of order. | ||||
outstream = reactor.makeoutputstream() | outstream = reactor.makeoutputstream() | ||||
reactor.onbytesresponseready(outstream, 3, b'response3') | reactor.onbytesresponseready(outstream, 3, b'response3') | ||||
reactor.onbytesresponseready(outstream, 1, b'response1') | reactor.onbytesresponseready(outstream, 1, b'response1') | ||||
reactor.onbytesresponseready(outstream, 5, b'response5') | reactor.onbytesresponseready(outstream, 5, b'response5') | ||||
result = reactor.oninputeof() | result = reactor.oninputeof() | ||||
self.assertaction(result, 'sendframes') | self.assertaction(result, b'sendframes') | ||||
self.assertframesequal(result[1]['framegen'], [ | self.assertframesequal(result[1][b'framegen'], [ | ||||
b'3 2 stream-begin bytes-response eos response3', | b'3 2 stream-begin bytes-response eos response3', | ||||
b'1 2 0 bytes-response eos response1', | b'1 2 0 bytes-response eos response1', | ||||
b'5 2 0 bytes-response eos response5', | b'5 2 0 bytes-response eos response5', | ||||
]) | ]) | ||||
def testduplicaterequestonactivecommand(self): | def testduplicaterequestonactivecommand(self): | ||||
"""Receiving a request ID that matches a request that isn't finished.""" | """Receiving a request ID that matches a request that isn't finished.""" | ||||
reactor = makereactor() | reactor = makereactor() | ||||
stream = framing.stream(1) | stream = framing.stream(1) | ||||
list(sendcommandframes(reactor, stream, 1, b'command1', {})) | list(sendcommandframes(reactor, stream, 1, b'command1', {})) | ||||
results = list(sendcommandframes(reactor, stream, 1, b'command1', {})) | results = list(sendcommandframes(reactor, stream, 1, b'command1', {})) | ||||
self.assertaction(results[0], 'error') | self.assertaction(results[0], b'error') | ||||
self.assertEqual(results[0][1], { | self.assertEqual(results[0][1], { | ||||
'message': b'request with ID 1 is already active', | b'message': b'request with ID 1 is already active', | ||||
}) | }) | ||||
def testduplicaterequestonactivecommandnosend(self): | def testduplicaterequestonactivecommandnosend(self): | ||||
"""Same as above but we've registered a response but haven't sent it.""" | """Same as above but we've registered a response but haven't sent it.""" | ||||
reactor = makereactor() | reactor = makereactor() | ||||
instream = framing.stream(1) | instream = framing.stream(1) | ||||
list(sendcommandframes(reactor, instream, 1, b'command1', {})) | list(sendcommandframes(reactor, instream, 1, b'command1', {})) | ||||
outstream = reactor.makeoutputstream() | outstream = reactor.makeoutputstream() | ||||
reactor.onbytesresponseready(outstream, 1, b'response') | reactor.onbytesresponseready(outstream, 1, b'response') | ||||
# We've registered the response but haven't sent it. From the | # We've registered the response but haven't sent it. From the | ||||
# perspective of the reactor, the command is still active. | # perspective of the reactor, the command is still active. | ||||
results = list(sendcommandframes(reactor, instream, 1, b'command1', {})) | results = list(sendcommandframes(reactor, instream, 1, b'command1', {})) | ||||
self.assertaction(results[0], 'error') | self.assertaction(results[0], b'error') | ||||
self.assertEqual(results[0][1], { | self.assertEqual(results[0][1], { | ||||
'message': b'request with ID 1 is already active', | b'message': b'request with ID 1 is already active', | ||||
}) | }) | ||||
def testduplicaterequestaftersend(self): | def testduplicaterequestaftersend(self): | ||||
"""We can use a duplicate request ID after we've sent the response.""" | """We can use a duplicate request ID after we've sent the response.""" | ||||
reactor = makereactor() | reactor = makereactor() | ||||
instream = framing.stream(1) | instream = framing.stream(1) | ||||
list(sendcommandframes(reactor, instream, 1, b'command1', {})) | list(sendcommandframes(reactor, instream, 1, b'command1', {})) | ||||
outstream = reactor.makeoutputstream() | outstream = reactor.makeoutputstream() | ||||
res = reactor.onbytesresponseready(outstream, 1, b'response') | res = reactor.onbytesresponseready(outstream, 1, b'response') | ||||
list(res[1]['framegen']) | list(res[1][b'framegen']) | ||||
results = list(sendcommandframes(reactor, instream, 1, b'command1', {})) | results = list(sendcommandframes(reactor, instream, 1, b'command1', {})) | ||||
self.assertaction(results[0], 'runcommand') | self.assertaction(results[0], b'runcommand') | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
import silenttestrunner | import silenttestrunner | ||||
silenttestrunner.main(__name__) | silenttestrunner.main(__name__) |