tests/test-wireproto-serverreactor.py
changeset 37057 2ec1fb9de638
parent 37056 861e9d37e56e
child 37058 c5e9c3b47366
equal deleted inserted replaced
37056:861e9d37e56e 37057:2ec1fb9de638
    16     """Send a generator of frame bytearray to a reactor.
    16     """Send a generator of frame bytearray to a reactor.
    17 
    17 
    18     Emits a generator of results from ``onframerecv()`` calls.
    18     Emits a generator of results from ``onframerecv()`` calls.
    19     """
    19     """
    20     for frame in gen:
    20     for frame in gen:
    21         frametype, frameflags, framelength = framing.parseheader(frame)
    21         rid, frametype, frameflags, framelength = framing.parseheader(frame)
    22         payload = frame[framing.FRAME_HEADER_SIZE:]
    22         payload = frame[framing.FRAME_HEADER_SIZE:]
    23         assert len(payload) == framelength
    23         assert len(payload) == framelength
    24 
    24 
    25         yield reactor.onframerecv(frametype, frameflags, payload)
    25         yield reactor.onframerecv(rid, frametype, frameflags, payload)
    26 
    26 
    27 def sendcommandframes(reactor, cmd, args, datafh=None):
    27 def sendcommandframes(reactor, rid, cmd, args, datafh=None):
    28     """Generate frames to run a command and send them to a reactor."""
    28     """Generate frames to run a command and send them to a reactor."""
    29     return sendframes(reactor, framing.createcommandframes(cmd, args, datafh))
    29     return sendframes(reactor,
       
    30                       framing.createcommandframes(rid, cmd, args, datafh))
    30 
    31 
    31 class FrameTests(unittest.TestCase):
    32 class FrameTests(unittest.TestCase):
    32     def testdataexactframesize(self):
    33     def testdataexactframesize(self):
    33         data = util.bytesio(b'x' * framing.DEFAULT_MAX_FRAME_SIZE)
    34         data = util.bytesio(b'x' * framing.DEFAULT_MAX_FRAME_SIZE)
    34 
    35 
    35         frames = list(framing.createcommandframes(b'command', {}, data))
    36         frames = list(framing.createcommandframes(1, b'command', {}, data))
    36         self.assertEqual(frames, [
    37         self.assertEqual(frames, [
    37             ffs(b'command-name have-data command'),
    38             ffs(b'1 command-name have-data command'),
    38             ffs(b'command-data continuation %s' % data.getvalue()),
    39             ffs(b'1 command-data continuation %s' % data.getvalue()),
    39             ffs(b'command-data eos ')
    40             ffs(b'1 command-data eos ')
    40         ])
    41         ])
    41 
    42 
    42     def testdatamultipleframes(self):
    43     def testdatamultipleframes(self):
    43         data = util.bytesio(b'x' * (framing.DEFAULT_MAX_FRAME_SIZE + 1))
    44         data = util.bytesio(b'x' * (framing.DEFAULT_MAX_FRAME_SIZE + 1))
    44         frames = list(framing.createcommandframes(b'command', {}, data))
    45         frames = list(framing.createcommandframes(1, b'command', {}, data))
    45         self.assertEqual(frames, [
    46         self.assertEqual(frames, [
    46             ffs(b'command-name have-data command'),
    47             ffs(b'1 command-name have-data command'),
    47             ffs(b'command-data continuation %s' % (
    48             ffs(b'1 command-data continuation %s' % (
    48                 b'x' * framing.DEFAULT_MAX_FRAME_SIZE)),
    49                 b'x' * framing.DEFAULT_MAX_FRAME_SIZE)),
    49             ffs(b'command-data eos x'),
    50             ffs(b'1 command-data eos x'),
    50         ])
    51         ])
    51 
    52 
    52     def testargsanddata(self):
    53     def testargsanddata(self):
    53         data = util.bytesio(b'x' * 100)
    54         data = util.bytesio(b'x' * 100)
    54 
    55 
    55         frames = list(framing.createcommandframes(b'command', {
    56         frames = list(framing.createcommandframes(1, b'command', {
    56             b'key1': b'key1value',
    57             b'key1': b'key1value',
    57             b'key2': b'key2value',
    58             b'key2': b'key2value',
    58             b'key3': b'key3value',
    59             b'key3': b'key3value',
    59         }, data))
    60         }, data))
    60 
    61 
    61         self.assertEqual(frames, [
    62         self.assertEqual(frames, [
    62             ffs(b'command-name have-args|have-data command'),
    63             ffs(b'1 command-name have-args|have-data command'),
    63             ffs(br'command-argument 0 \x04\x00\x09\x00key1key1value'),
    64             ffs(br'1 command-argument 0 \x04\x00\x09\x00key1key1value'),
    64             ffs(br'command-argument 0 \x04\x00\x09\x00key2key2value'),
    65             ffs(br'1 command-argument 0 \x04\x00\x09\x00key2key2value'),
    65             ffs(br'command-argument eoa \x04\x00\x09\x00key3key3value'),
    66             ffs(br'1 command-argument eoa \x04\x00\x09\x00key3key3value'),
    66             ffs(b'command-data eos %s' % data.getvalue()),
    67             ffs(b'1 command-data eos %s' % data.getvalue()),
    67         ])
    68         ])
    68 
    69 
    69 class ServerReactorTests(unittest.TestCase):
    70 class ServerReactorTests(unittest.TestCase):
    70     def _sendsingleframe(self, reactor, s):
    71     def _sendsingleframe(self, reactor, s):
    71         results = list(sendframes(reactor, [ffs(s)]))
    72         results = list(sendframes(reactor, [ffs(s)]))
    84         self.assertEqual(list(frames), expected)
    85         self.assertEqual(list(frames), expected)
    85 
    86 
    86     def test1framecommand(self):
    87     def test1framecommand(self):
    87         """Receiving a command in a single frame yields request to run it."""
    88         """Receiving a command in a single frame yields request to run it."""
    88         reactor = makereactor()
    89         reactor = makereactor()
    89         results = list(sendcommandframes(reactor, b'mycommand', {}))
    90         results = list(sendcommandframes(reactor, 1, b'mycommand', {}))
    90         self.assertEqual(len(results), 1)
    91         self.assertEqual(len(results), 1)
    91         self.assertaction(results[0], 'runcommand')
    92         self.assertaction(results[0], 'runcommand')
    92         self.assertEqual(results[0][1], {
    93         self.assertEqual(results[0][1], {
       
    94             'requestid': 1,
    93             'command': b'mycommand',
    95             'command': b'mycommand',
    94             'args': {},
    96             'args': {},
    95             'data': None,
    97             'data': None,
    96         })
    98         })
    97 
    99 
    98         result = reactor.oninputeof()
   100         result = reactor.oninputeof()
    99         self.assertaction(result, 'noop')
   101         self.assertaction(result, 'noop')
   100 
   102 
   101     def test1argument(self):
   103     def test1argument(self):
   102         reactor = makereactor()
   104         reactor = makereactor()
   103         results = list(sendcommandframes(reactor, b'mycommand',
   105         results = list(sendcommandframes(reactor, 41, b'mycommand',
   104                                          {b'foo': b'bar'}))
   106                                          {b'foo': b'bar'}))
   105         self.assertEqual(len(results), 2)
   107         self.assertEqual(len(results), 2)
   106         self.assertaction(results[0], 'wantframe')
   108         self.assertaction(results[0], 'wantframe')
   107         self.assertaction(results[1], 'runcommand')
   109         self.assertaction(results[1], 'runcommand')
   108         self.assertEqual(results[1][1], {
   110         self.assertEqual(results[1][1], {
       
   111             'requestid': 41,
   109             'command': b'mycommand',
   112             'command': b'mycommand',
   110             'args': {b'foo': b'bar'},
   113             'args': {b'foo': b'bar'},
   111             'data': None,
   114             'data': None,
   112         })
   115         })
   113 
   116 
   114     def testmultiarguments(self):
   117     def testmultiarguments(self):
   115         reactor = makereactor()
   118         reactor = makereactor()
   116         results = list(sendcommandframes(reactor, b'mycommand',
   119         results = list(sendcommandframes(reactor, 1, b'mycommand',
   117                                          {b'foo': b'bar', b'biz': b'baz'}))
   120                                          {b'foo': b'bar', b'biz': b'baz'}))
   118         self.assertEqual(len(results), 3)
   121         self.assertEqual(len(results), 3)
   119         self.assertaction(results[0], 'wantframe')
   122         self.assertaction(results[0], 'wantframe')
   120         self.assertaction(results[1], 'wantframe')
   123         self.assertaction(results[1], 'wantframe')
   121         self.assertaction(results[2], 'runcommand')
   124         self.assertaction(results[2], 'runcommand')
   122         self.assertEqual(results[2][1], {
   125         self.assertEqual(results[2][1], {
       
   126             'requestid': 1,
   123             'command': b'mycommand',
   127             'command': b'mycommand',
   124             'args': {b'foo': b'bar', b'biz': b'baz'},
   128             'args': {b'foo': b'bar', b'biz': b'baz'},
   125             'data': None,
   129             'data': None,
   126         })
   130         })
   127 
   131 
   128     def testsimplecommanddata(self):
   132     def testsimplecommanddata(self):
   129         reactor = makereactor()
   133         reactor = makereactor()
   130         results = list(sendcommandframes(reactor, b'mycommand', {},
   134         results = list(sendcommandframes(reactor, 1, b'mycommand', {},
   131                                          util.bytesio(b'data!')))
   135                                          util.bytesio(b'data!')))
   132         self.assertEqual(len(results), 2)
   136         self.assertEqual(len(results), 2)
   133         self.assertaction(results[0], 'wantframe')
   137         self.assertaction(results[0], 'wantframe')
   134         self.assertaction(results[1], 'runcommand')
   138         self.assertaction(results[1], 'runcommand')
   135         self.assertEqual(results[1][1], {
   139         self.assertEqual(results[1][1], {
       
   140             'requestid': 1,
   136             'command': b'mycommand',
   141             'command': b'mycommand',
   137             'args': {},
   142             'args': {},
   138             'data': b'data!',
   143             'data': b'data!',
   139         })
   144         })
   140 
   145 
   141     def testmultipledataframes(self):
   146     def testmultipledataframes(self):
   142         frames = [
   147         frames = [
   143             ffs(b'command-name have-data mycommand'),
   148             ffs(b'1 command-name have-data mycommand'),
   144             ffs(b'command-data continuation data1'),
   149             ffs(b'1 command-data continuation data1'),
   145             ffs(b'command-data continuation data2'),
   150             ffs(b'1 command-data continuation data2'),
   146             ffs(b'command-data eos data3'),
   151             ffs(b'1 command-data eos data3'),
   147         ]
   152         ]
   148 
   153 
   149         reactor = makereactor()
   154         reactor = makereactor()
   150         results = list(sendframes(reactor, frames))
   155         results = list(sendframes(reactor, frames))
   151         self.assertEqual(len(results), 4)
   156         self.assertEqual(len(results), 4)
   152         for i in range(3):
   157         for i in range(3):
   153             self.assertaction(results[i], 'wantframe')
   158             self.assertaction(results[i], 'wantframe')
   154         self.assertaction(results[3], 'runcommand')
   159         self.assertaction(results[3], 'runcommand')
   155         self.assertEqual(results[3][1], {
   160         self.assertEqual(results[3][1], {
       
   161             'requestid': 1,
   156             'command': b'mycommand',
   162             'command': b'mycommand',
   157             'args': {},
   163             'args': {},
   158             'data': b'data1data2data3',
   164             'data': b'data1data2data3',
   159         })
   165         })
   160 
   166 
   161     def testargumentanddata(self):
   167     def testargumentanddata(self):
   162         frames = [
   168         frames = [
   163             ffs(b'command-name have-args|have-data command'),
   169             ffs(b'1 command-name have-args|have-data command'),
   164             ffs(br'command-argument 0 \x03\x00\x03\x00keyval'),
   170             ffs(br'1 command-argument 0 \x03\x00\x03\x00keyval'),
   165             ffs(br'command-argument eoa \x03\x00\x03\x00foobar'),
   171             ffs(br'1 command-argument eoa \x03\x00\x03\x00foobar'),
   166             ffs(b'command-data continuation value1'),
   172             ffs(b'1 command-data continuation value1'),
   167             ffs(b'command-data eos value2'),
   173             ffs(b'1 command-data eos value2'),
   168         ]
   174         ]
   169 
   175 
   170         reactor = makereactor()
   176         reactor = makereactor()
   171         results = list(sendframes(reactor, frames))
   177         results = list(sendframes(reactor, frames))
   172 
   178 
   173         self.assertaction(results[-1], 'runcommand')
   179         self.assertaction(results[-1], 'runcommand')
   174         self.assertEqual(results[-1][1], {
   180         self.assertEqual(results[-1][1], {
       
   181             'requestid': 1,
   175             'command': b'command',
   182             'command': b'command',
   176             'args': {
   183             'args': {
   177                 b'key': b'val',
   184                 b'key': b'val',
   178                 b'foo': b'bar',
   185                 b'foo': b'bar',
   179             },
   186             },
   181         })
   188         })
   182 
   189 
   183     def testunexpectedcommandargument(self):
   190     def testunexpectedcommandargument(self):
   184         """Command argument frame when not running a command is an error."""
   191         """Command argument frame when not running a command is an error."""
   185         result = self._sendsingleframe(makereactor(),
   192         result = self._sendsingleframe(makereactor(),
   186                                        b'command-argument 0 ignored')
   193                                        b'1 command-argument 0 ignored')
   187         self.assertaction(result, 'error')
   194         self.assertaction(result, 'error')
   188         self.assertEqual(result[1], {
   195         self.assertEqual(result[1], {
   189             'message': b'expected command frame; got 2',
   196             'message': b'expected command frame; got 2',
   190         })
   197         })
   191 
   198 
   192     def testunexpectedcommanddata(self):
   199     def testunexpectedcommanddata(self):
   193         """Command argument frame when not running a command is an error."""
   200         """Command argument frame when not running a command is an error."""
   194         result = self._sendsingleframe(makereactor(),
   201         result = self._sendsingleframe(makereactor(),
   195                                        b'command-data 0 ignored')
   202                                        b'1 command-data 0 ignored')
   196         self.assertaction(result, 'error')
   203         self.assertaction(result, 'error')
   197         self.assertEqual(result[1], {
   204         self.assertEqual(result[1], {
   198             'message': b'expected command frame; got 3',
   205             'message': b'expected command frame; got 3',
   199         })
   206         })
   200 
   207 
   201     def testmissingcommandframeflags(self):
   208     def testmissingcommandframeflags(self):
   202         """Command name frame must have flags set."""
   209         """Command name frame must have flags set."""
   203         result = self._sendsingleframe(makereactor(),
   210         result = self._sendsingleframe(makereactor(),
   204                                        b'command-name 0 command')
   211                                        b'1 command-name 0 command')
   205         self.assertaction(result, 'error')
   212         self.assertaction(result, 'error')
   206         self.assertEqual(result[1], {
   213         self.assertEqual(result[1], {
   207             'message': b'missing frame flags on command frame',
   214             'message': b'missing frame flags on command frame',
   208         })
   215         })
   209 
   216 
   210     def testmissingargumentframe(self):
   217     def testmissingargumentframe(self):
   211         frames = [
   218         frames = [
   212             ffs(b'command-name have-args command'),
   219             ffs(b'1 command-name have-args command'),
   213             ffs(b'command-name 0 ignored'),
   220             ffs(b'1 command-name 0 ignored'),
   214         ]
   221         ]
   215 
   222 
   216         results = list(sendframes(makereactor(), frames))
   223         results = list(sendframes(makereactor(), frames))
   217         self.assertEqual(len(results), 2)
   224         self.assertEqual(len(results), 2)
   218         self.assertaction(results[0], 'wantframe')
   225         self.assertaction(results[0], 'wantframe')
   222         })
   229         })
   223 
   230 
   224     def testincompleteargumentname(self):
   231     def testincompleteargumentname(self):
   225         """Argument frame with incomplete name."""
   232         """Argument frame with incomplete name."""
   226         frames = [
   233         frames = [
   227             ffs(b'command-name have-args command1'),
   234             ffs(b'1 command-name have-args command1'),
   228             ffs(br'command-argument eoa \x04\x00\xde\xadfoo'),
   235             ffs(br'1 command-argument eoa \x04\x00\xde\xadfoo'),
   229         ]
   236         ]
   230 
   237 
   231         results = list(sendframes(makereactor(), frames))
   238         results = list(sendframes(makereactor(), frames))
   232         self.assertEqual(len(results), 2)
   239         self.assertEqual(len(results), 2)
   233         self.assertaction(results[0], 'wantframe')
   240         self.assertaction(results[0], 'wantframe')
   237         })
   244         })
   238 
   245 
   239     def testincompleteargumentvalue(self):
   246     def testincompleteargumentvalue(self):
   240         """Argument frame with incomplete value."""
   247         """Argument frame with incomplete value."""
   241         frames = [
   248         frames = [
   242             ffs(b'command-name have-args command'),
   249             ffs(b'1 command-name have-args command'),
   243             ffs(br'command-argument eoa \x03\x00\xaa\xaafoopartialvalue'),
   250             ffs(br'1 command-argument eoa \x03\x00\xaa\xaafoopartialvalue'),
   244         ]
   251         ]
   245 
   252 
   246         results = list(sendframes(makereactor(), frames))
   253         results = list(sendframes(makereactor(), frames))
   247         self.assertEqual(len(results), 2)
   254         self.assertEqual(len(results), 2)
   248         self.assertaction(results[0], 'wantframe')
   255         self.assertaction(results[0], 'wantframe')
   251             'message': b'malformed argument frame: partial argument value',
   258             'message': b'malformed argument frame: partial argument value',
   252         })
   259         })
   253 
   260 
   254     def testmissingcommanddataframe(self):
   261     def testmissingcommanddataframe(self):
   255         frames = [
   262         frames = [
   256             ffs(b'command-name have-data command1'),
   263             ffs(b'1 command-name have-data command1'),
   257             ffs(b'command-name eos command2'),
   264             ffs(b'1 command-name eos command2'),
   258         ]
   265         ]
   259         results = list(sendframes(makereactor(), frames))
   266         results = list(sendframes(makereactor(), frames))
   260         self.assertEqual(len(results), 2)
   267         self.assertEqual(len(results), 2)
   261         self.assertaction(results[0], 'wantframe')
   268         self.assertaction(results[0], 'wantframe')
   262         self.assertaction(results[1], 'error')
   269         self.assertaction(results[1], 'error')
   264             'message': b'expected command data frame; got 1',
   271             'message': b'expected command data frame; got 1',
   265         })
   272         })
   266 
   273 
   267     def testmissingcommanddataframeflags(self):
   274     def testmissingcommanddataframeflags(self):
   268         frames = [
   275         frames = [
   269             ffs(b'command-name have-data command1'),
   276             ffs(b'1 command-name have-data command1'),
   270             ffs(b'command-data 0 data'),
   277             ffs(b'1 command-data 0 data'),
   271         ]
   278         ]
   272         results = list(sendframes(makereactor(), frames))
   279         results = list(sendframes(makereactor(), frames))
   273         self.assertEqual(len(results), 2)
   280         self.assertEqual(len(results), 2)
   274         self.assertaction(results[0], 'wantframe')
   281         self.assertaction(results[0], 'wantframe')
   275         self.assertaction(results[1], 'error')
   282         self.assertaction(results[1], 'error')
   278         })
   285         })
   279 
   286 
   280     def testsimpleresponse(self):
   287     def testsimpleresponse(self):
   281         """Bytes response to command sends result frames."""
   288         """Bytes response to command sends result frames."""
   282         reactor = makereactor()
   289         reactor = makereactor()
   283         list(sendcommandframes(reactor, b'mycommand', {}))
   290         list(sendcommandframes(reactor, 1, b'mycommand', {}))
   284 
   291 
   285         result = reactor.onbytesresponseready(b'response')
   292         result = reactor.onbytesresponseready(1, b'response')
   286         self.assertaction(result, 'sendframes')
   293         self.assertaction(result, 'sendframes')
   287         self.assertframesequal(result[1]['framegen'], [
   294         self.assertframesequal(result[1]['framegen'], [
   288             b'bytes-response eos response',
   295             b'1 bytes-response eos response',
   289         ])
   296         ])
   290 
   297 
   291     def testmultiframeresponse(self):
   298     def testmultiframeresponse(self):
   292         """Bytes response spanning multiple frames is handled."""
   299         """Bytes response spanning multiple frames is handled."""
   293         first = b'x' * framing.DEFAULT_MAX_FRAME_SIZE
   300         first = b'x' * framing.DEFAULT_MAX_FRAME_SIZE
   294         second = b'y' * 100
   301         second = b'y' * 100
   295 
   302 
   296         reactor = makereactor()
   303         reactor = makereactor()
   297         list(sendcommandframes(reactor, b'mycommand', {}))
   304         list(sendcommandframes(reactor, 1, b'mycommand', {}))
   298 
   305 
   299         result = reactor.onbytesresponseready(first + second)
   306         result = reactor.onbytesresponseready(1, first + second)
   300         self.assertaction(result, 'sendframes')
   307         self.assertaction(result, 'sendframes')
   301         self.assertframesequal(result[1]['framegen'], [
   308         self.assertframesequal(result[1]['framegen'], [
   302             b'bytes-response continuation %s' % first,
   309             b'1 bytes-response continuation %s' % first,
   303             b'bytes-response eos %s' % second,
   310             b'1 bytes-response eos %s' % second,
   304         ])
   311         ])
   305 
   312 
   306     def testapplicationerror(self):
   313     def testapplicationerror(self):
   307         reactor = makereactor()
   314         reactor = makereactor()
   308         list(sendcommandframes(reactor, b'mycommand', {}))
   315         list(sendcommandframes(reactor, 1, b'mycommand', {}))
   309 
   316 
   310         result = reactor.onapplicationerror(b'some message')
   317         result = reactor.onapplicationerror(1, b'some message')
   311         self.assertaction(result, 'sendframes')
   318         self.assertaction(result, 'sendframes')
   312         self.assertframesequal(result[1]['framegen'], [
   319         self.assertframesequal(result[1]['framegen'], [
   313             b'error-response application some message',
   320             b'1 error-response application some message',
   314         ])
   321         ])
   315 
   322 
   316     def test1commanddeferresponse(self):
   323     def test1commanddeferresponse(self):
   317         """Responses when in deferred output mode are delayed until EOF."""
   324         """Responses when in deferred output mode are delayed until EOF."""
   318         reactor = makereactor(deferoutput=True)
   325         reactor = makereactor(deferoutput=True)
   319         results = list(sendcommandframes(reactor, b'mycommand', {}))
   326         results = list(sendcommandframes(reactor, 1, b'mycommand', {}))
   320         self.assertEqual(len(results), 1)
   327         self.assertEqual(len(results), 1)
   321         self.assertaction(results[0], 'runcommand')
   328         self.assertaction(results[0], 'runcommand')
   322 
   329 
   323         result = reactor.onbytesresponseready(b'response')
   330         result = reactor.onbytesresponseready(1, b'response')
   324         self.assertaction(result, 'noop')
   331         self.assertaction(result, 'noop')
   325         result = reactor.oninputeof()
   332         result = reactor.oninputeof()
   326         self.assertaction(result, 'sendframes')
   333         self.assertaction(result, 'sendframes')
   327         self.assertframesequal(result[1]['framegen'], [
   334         self.assertframesequal(result[1]['framegen'], [
   328             b'bytes-response eos response',
   335             b'1 bytes-response eos response',
   329         ])
   336         ])
   330 
   337 
   331     def testmultiplecommanddeferresponse(self):
   338     def testmultiplecommanddeferresponse(self):
   332         reactor = makereactor(deferoutput=True)
   339         reactor = makereactor(deferoutput=True)
   333         list(sendcommandframes(reactor, b'command1', {}))
   340         list(sendcommandframes(reactor, 1, b'command1', {}))
   334         list(sendcommandframes(reactor, b'command2', {}))
   341         list(sendcommandframes(reactor, 3, b'command2', {}))
   335 
   342 
   336         result = reactor.onbytesresponseready(b'response1')
   343         result = reactor.onbytesresponseready(1, b'response1')
   337         self.assertaction(result, 'noop')
   344         self.assertaction(result, 'noop')
   338         result = reactor.onbytesresponseready(b'response2')
   345         result = reactor.onbytesresponseready(3, b'response2')
   339         self.assertaction(result, 'noop')
   346         self.assertaction(result, 'noop')
   340         result = reactor.oninputeof()
   347         result = reactor.oninputeof()
   341         self.assertaction(result, 'sendframes')
   348         self.assertaction(result, 'sendframes')
   342         self.assertframesequal(result[1]['framegen'], [
   349         self.assertframesequal(result[1]['framegen'], [
   343             b'bytes-response eos response1',
   350             b'1 bytes-response eos response1',
   344             b'bytes-response eos response2'
   351             b'3 bytes-response eos response2'
       
   352         ])
       
   353 
       
   354     def testrequestidtracking(self):
       
   355         reactor = makereactor(deferoutput=True)
       
   356         list(sendcommandframes(reactor, 1, b'command1', {}))
       
   357         list(sendcommandframes(reactor, 3, b'command2', {}))
       
   358         list(sendcommandframes(reactor, 5, b'command3', {}))
       
   359 
       
   360         # Register results for commands out of order.
       
   361         reactor.onbytesresponseready(3, b'response3')
       
   362         reactor.onbytesresponseready(1, b'response1')
       
   363         reactor.onbytesresponseready(5, b'response5')
       
   364 
       
   365         result = reactor.oninputeof()
       
   366         self.assertaction(result, 'sendframes')
       
   367         self.assertframesequal(result[1]['framegen'], [
       
   368             b'3 bytes-response eos response3',
       
   369             b'1 bytes-response eos response1',
       
   370             b'5 bytes-response eos response5',
   345         ])
   371         ])
   346 
   372 
   347 if __name__ == '__main__':
   373 if __name__ == '__main__':
   348     import silenttestrunner
   374     import silenttestrunner
   349     silenttestrunner.main(__name__)
   375     silenttestrunner.main(__name__)