##// END OF EJS Templates
wireproto: start to associate frame generation with a stream...
Gregory Szorc -
r37303:3ed34454 default
parent child Browse files
Show More
@@ -218,7 +218,7 b' def readframe(fh):'
218 218
219 219 return frame(h.requestid, h.typeid, h.flags, payload)
220 220
221 def createcommandframes(requestid, cmd, args, datafh=None):
221 def createcommandframes(stream, requestid, cmd, args, datafh=None):
222 222 """Create frames necessary to transmit a request to run a command.
223 223
224 224 This is a generator of bytearrays. Each item represents a frame
@@ -233,8 +233,8 b' def createcommandframes(requestid, cmd, '
233 233 if not flags:
234 234 flags |= FLAG_COMMAND_NAME_EOS
235 235
236 yield makeframe(requestid=requestid, typeid=FRAME_TYPE_COMMAND_NAME,
237 flags=flags, payload=cmd)
236 yield stream.makeframe(requestid=requestid, typeid=FRAME_TYPE_COMMAND_NAME,
237 flags=flags, payload=cmd)
238 238
239 239 for i, k in enumerate(sorted(args)):
240 240 v = args[k]
@@ -250,10 +250,10 b' def createcommandframes(requestid, cmd, '
250 250 payload[offset:offset + len(v)] = v
251 251
252 252 flags = FLAG_COMMAND_ARGUMENT_EOA if last else 0
253 yield makeframe(requestid=requestid,
254 typeid=FRAME_TYPE_COMMAND_ARGUMENT,
255 flags=flags,
256 payload=payload)
253 yield stream.makeframe(requestid=requestid,
254 typeid=FRAME_TYPE_COMMAND_ARGUMENT,
255 flags=flags,
256 payload=payload)
257 257
258 258 if datafh:
259 259 while True:
@@ -267,15 +267,15 b' def createcommandframes(requestid, cmd, '
267 267 assert datafh.read(1) == b''
268 268 done = True
269 269
270 yield makeframe(requestid=requestid,
271 typeid=FRAME_TYPE_COMMAND_DATA,
272 flags=flags,
273 payload=data)
270 yield stream.makeframe(requestid=requestid,
271 typeid=FRAME_TYPE_COMMAND_DATA,
272 flags=flags,
273 payload=data)
274 274
275 275 if done:
276 276 break
277 277
278 def createbytesresponseframesfrombytes(requestid, data,
278 def createbytesresponseframesfrombytes(stream, requestid, data,
279 279 maxframesize=DEFAULT_MAX_FRAME_SIZE):
280 280 """Create a raw frame to send a bytes response from static bytes input.
281 281
@@ -284,10 +284,10 b' def createbytesresponseframesfrombytes(r'
284 284
285 285 # Simple case of a single frame.
286 286 if len(data) <= maxframesize:
287 yield makeframe(requestid=requestid,
288 typeid=FRAME_TYPE_BYTES_RESPONSE,
289 flags=FLAG_BYTES_RESPONSE_EOS,
290 payload=data)
287 yield stream.makeframe(requestid=requestid,
288 typeid=FRAME_TYPE_BYTES_RESPONSE,
289 flags=FLAG_BYTES_RESPONSE_EOS,
290 payload=data)
291 291 return
292 292
293 293 offset = 0
@@ -301,15 +301,15 b' def createbytesresponseframesfrombytes(r'
301 301 else:
302 302 flags = FLAG_BYTES_RESPONSE_CONTINUATION
303 303
304 yield makeframe(requestid=requestid,
305 typeid=FRAME_TYPE_BYTES_RESPONSE,
306 flags=flags,
307 payload=chunk)
304 yield stream.makeframe(requestid=requestid,
305 typeid=FRAME_TYPE_BYTES_RESPONSE,
306 flags=flags,
307 payload=chunk)
308 308
309 309 if done:
310 310 break
311 311
312 def createerrorframe(requestid, msg, protocol=False, application=False):
312 def createerrorframe(stream, requestid, msg, protocol=False, application=False):
313 313 # TODO properly handle frame size limits.
314 314 assert len(msg) <= DEFAULT_MAX_FRAME_SIZE
315 315
@@ -319,12 +319,12 b' def createerrorframe(requestid, msg, pro'
319 319 if application:
320 320 flags |= FLAG_ERROR_RESPONSE_APPLICATION
321 321
322 yield makeframe(requestid=requestid,
323 typeid=FRAME_TYPE_ERROR_RESPONSE,
324 flags=flags,
325 payload=msg)
322 yield stream.makeframe(requestid=requestid,
323 typeid=FRAME_TYPE_ERROR_RESPONSE,
324 flags=flags,
325 payload=msg)
326 326
327 def createtextoutputframe(requestid, atoms):
327 def createtextoutputframe(stream, requestid, atoms):
328 328 """Create a text output frame to render text to people.
329 329
330 330 ``atoms`` is a 3-tuple of (formatting string, args, labels).
@@ -390,10 +390,20 b' def createtextoutputframe(requestid, ato'
390 390 if bytesleft < 0:
391 391 raise ValueError('cannot encode data in a single frame')
392 392
393 yield makeframe(requestid=requestid,
394 typeid=FRAME_TYPE_TEXT_OUTPUT,
395 flags=0,
396 payload=b''.join(atomchunks))
393 yield stream.makeframe(requestid=requestid,
394 typeid=FRAME_TYPE_TEXT_OUTPUT,
395 flags=0,
396 payload=b''.join(atomchunks))
397
398 class stream(object):
399 """Represents a logical unidirectional series of frames."""
400
401 def makeframe(self, requestid, typeid, flags, payload):
402 """Create a frame to be sent out over this stream.
403
404 Only returns the frame instance. Does not actually send it.
405 """
406 return makeframe(requestid, typeid, flags, payload)
397 407
398 408 class serverreactor(object):
399 409 """Holds state of a server handling frame-based protocol requests.
@@ -498,13 +508,14 b' class serverreactor(object):'
498 508
499 509 return meth(frame)
500 510
501 def onbytesresponseready(self, requestid, data):
511 def onbytesresponseready(self, stream, requestid, data):
502 512 """Signal that a bytes response is ready to be sent to the client.
503 513
504 514 The raw bytes response is passed as an argument.
505 515 """
506 516 def sendframes():
507 for frame in createbytesresponseframesfrombytes(requestid, data):
517 for frame in createbytesresponseframesfrombytes(stream, requestid,
518 data):
508 519 yield frame
509 520
510 521 self._activecommands.remove(requestid)
@@ -540,9 +551,10 b' class serverreactor(object):'
540 551 'framegen': makegen(),
541 552 }
542 553
543 def onapplicationerror(self, requestid, msg):
554 def onapplicationerror(self, stream, requestid, msg):
544 555 return 'sendframes', {
545 'framegen': createerrorframe(requestid, msg, application=True),
556 'framegen': createerrorframe(stream, requestid, msg,
557 application=True),
546 558 }
547 559
548 560 def _makeerrorresult(self, msg):
@@ -546,9 +546,11 b' def _httpv2runcommand(ui, repo, req, res'
546 546
547 547 res.status = b'200 OK'
548 548 res.headers[b'Content-Type'] = FRAMINGTYPE
549 stream = wireprotoframing.stream()
549 550
550 551 if isinstance(rsp, wireprototypes.bytesresponse):
551 action, meta = reactor.onbytesresponseready(command['requestid'],
552 action, meta = reactor.onbytesresponseready(stream,
553 command['requestid'],
552 554 rsp.data)
553 555 else:
554 556 action, meta = reactor.onapplicationerror(
@@ -27,16 +27,19 b' def sendframes(reactor, gen):'
27 27 header.flags,
28 28 payload))
29 29
30 def sendcommandframes(reactor, rid, cmd, args, datafh=None):
30 def sendcommandframes(reactor, stream, rid, cmd, args, datafh=None):
31 31 """Generate frames to run a command and send them to a reactor."""
32 32 return sendframes(reactor,
33 framing.createcommandframes(rid, cmd, args, datafh))
33 framing.createcommandframes(stream, rid, cmd, args,
34 datafh))
34 35
35 36 class FrameTests(unittest.TestCase):
36 37 def testdataexactframesize(self):
37 38 data = util.bytesio(b'x' * framing.DEFAULT_MAX_FRAME_SIZE)
38 39
39 frames = list(framing.createcommandframes(1, b'command', {}, data))
40 stream = framing.stream()
41 frames = list(framing.createcommandframes(stream, 1, b'command',
42 {}, data))
40 43 self.assertEqual(frames, [
41 44 ffs(b'1 command-name have-data command'),
42 45 ffs(b'1 command-data continuation %s' % data.getvalue()),
@@ -45,7 +48,10 b' class FrameTests(unittest.TestCase):'
45 48
46 49 def testdatamultipleframes(self):
47 50 data = util.bytesio(b'x' * (framing.DEFAULT_MAX_FRAME_SIZE + 1))
48 frames = list(framing.createcommandframes(1, b'command', {}, data))
51
52 stream = framing.stream()
53 frames = list(framing.createcommandframes(stream, 1, b'command', {},
54 data))
49 55 self.assertEqual(frames, [
50 56 ffs(b'1 command-name have-data command'),
51 57 ffs(b'1 command-data continuation %s' % (
@@ -56,7 +62,8 b' class FrameTests(unittest.TestCase):'
56 62 def testargsanddata(self):
57 63 data = util.bytesio(b'x' * 100)
58 64
59 frames = list(framing.createcommandframes(1, b'command', {
65 stream = framing.stream()
66 frames = list(framing.createcommandframes(stream, 1, b'command', {
60 67 b'key1': b'key1value',
61 68 b'key2': b'key2value',
62 69 b'key3': b'key3value',
@@ -75,51 +82,54 b' class FrameTests(unittest.TestCase):'
75 82 with self.assertRaisesRegexp(ValueError,
76 83 'cannot use more than 255 formatting'):
77 84 args = [b'x' for i in range(256)]
78 list(framing.createtextoutputframe(1, [(b'bleh', args, [])]))
85 list(framing.createtextoutputframe(None, 1,
86 [(b'bleh', args, [])]))
79 87
80 88 def testtextoutputexcessivelabels(self):
81 89 """At most 255 labels are allowed."""
82 90 with self.assertRaisesRegexp(ValueError,
83 91 'cannot use more than 255 labels'):
84 92 labels = [b'l' for i in range(256)]
85 list(framing.createtextoutputframe(1, [(b'bleh', [], labels)]))
93 list(framing.createtextoutputframe(None, 1,
94 [(b'bleh', [], labels)]))
86 95
87 96 def testtextoutputformattingstringtype(self):
88 97 """Formatting string must be bytes."""
89 98 with self.assertRaisesRegexp(ValueError, 'must use bytes formatting '):
90 list(framing.createtextoutputframe(1, [
99 list(framing.createtextoutputframe(None, 1, [
91 100 (b'foo'.decode('ascii'), [], [])]))
92 101
93 102 def testtextoutputargumentbytes(self):
94 103 with self.assertRaisesRegexp(ValueError, 'must use bytes for argument'):
95 list(framing.createtextoutputframe(1, [
104 list(framing.createtextoutputframe(None, 1, [
96 105 (b'foo', [b'foo'.decode('ascii')], [])]))
97 106
98 107 def testtextoutputlabelbytes(self):
99 108 with self.assertRaisesRegexp(ValueError, 'must use bytes for labels'):
100 list(framing.createtextoutputframe(1, [
109 list(framing.createtextoutputframe(None, 1, [
101 110 (b'foo', [], [b'foo'.decode('ascii')])]))
102 111
103 112 def testtextoutputtoolongformatstring(self):
104 113 with self.assertRaisesRegexp(ValueError,
105 114 'formatting string cannot be longer than'):
106 list(framing.createtextoutputframe(1, [
115 list(framing.createtextoutputframe(None, 1, [
107 116 (b'x' * 65536, [], [])]))
108 117
109 118 def testtextoutputtoolongargumentstring(self):
110 119 with self.assertRaisesRegexp(ValueError,
111 120 'argument string cannot be longer than'):
112 list(framing.createtextoutputframe(1, [
121 list(framing.createtextoutputframe(None, 1, [
113 122 (b'bleh', [b'x' * 65536], [])]))
114 123
115 124 def testtextoutputtoolonglabelstring(self):
116 125 with self.assertRaisesRegexp(ValueError,
117 126 'label string cannot be longer than'):
118 list(framing.createtextoutputframe(1, [
127 list(framing.createtextoutputframe(None, 1, [
119 128 (b'bleh', [], [b'x' * 65536])]))
120 129
121 130 def testtextoutput1simpleatom(self):
122 val = list(framing.createtextoutputframe(1, [
131 stream = framing.stream()
132 val = list(framing.createtextoutputframe(stream, 1, [
123 133 (b'foo', [], [])]))
124 134
125 135 self.assertEqual(val, [
@@ -127,7 +137,8 b' class FrameTests(unittest.TestCase):'
127 137 ])
128 138
129 139 def testtextoutput2simpleatoms(self):
130 val = list(framing.createtextoutputframe(1, [
140 stream = framing.stream()
141 val = list(framing.createtextoutputframe(stream, 1, [
131 142 (b'foo', [], []),
132 143 (b'bar', [], []),
133 144 ]))
@@ -137,7 +148,8 b' class FrameTests(unittest.TestCase):'
137 148 ])
138 149
139 150 def testtextoutput1arg(self):
140 val = list(framing.createtextoutputframe(1, [
151 stream = framing.stream()
152 val = list(framing.createtextoutputframe(stream, 1, [
141 153 (b'foo %s', [b'val1'], []),
142 154 ]))
143 155
@@ -146,7 +158,8 b' class FrameTests(unittest.TestCase):'
146 158 ])
147 159
148 160 def testtextoutput2arg(self):
149 val = list(framing.createtextoutputframe(1, [
161 stream = framing.stream()
162 val = list(framing.createtextoutputframe(stream, 1, [
150 163 (b'foo %s %s', [b'val', b'value'], []),
151 164 ]))
152 165
@@ -156,7 +169,8 b' class FrameTests(unittest.TestCase):'
156 169 ])
157 170
158 171 def testtextoutput1label(self):
159 val = list(framing.createtextoutputframe(1, [
172 stream = framing.stream()
173 val = list(framing.createtextoutputframe(stream, 1, [
160 174 (b'foo', [], [b'label']),
161 175 ]))
162 176
@@ -165,7 +179,8 b' class FrameTests(unittest.TestCase):'
165 179 ])
166 180
167 181 def testargandlabel(self):
168 val = list(framing.createtextoutputframe(1, [
182 stream = framing.stream()
183 val = list(framing.createtextoutputframe(stream, 1, [
169 184 (b'foo %s', [b'arg'], [b'label']),
170 185 ]))
171 186
@@ -193,7 +208,8 b' class ServerReactorTests(unittest.TestCa'
193 208 def test1framecommand(self):
194 209 """Receiving a command in a single frame yields request to run it."""
195 210 reactor = makereactor()
196 results = list(sendcommandframes(reactor, 1, b'mycommand', {}))
211 stream = framing.stream()
212 results = list(sendcommandframes(reactor, stream, 1, b'mycommand', {}))
197 213 self.assertEqual(len(results), 1)
198 214 self.assertaction(results[0], 'runcommand')
199 215 self.assertEqual(results[0][1], {
@@ -208,7 +224,8 b' class ServerReactorTests(unittest.TestCa'
208 224
209 225 def test1argument(self):
210 226 reactor = makereactor()
211 results = list(sendcommandframes(reactor, 41, b'mycommand',
227 stream = framing.stream()
228 results = list(sendcommandframes(reactor, stream, 41, b'mycommand',
212 229 {b'foo': b'bar'}))
213 230 self.assertEqual(len(results), 2)
214 231 self.assertaction(results[0], 'wantframe')
@@ -222,7 +239,8 b' class ServerReactorTests(unittest.TestCa'
222 239
223 240 def testmultiarguments(self):
224 241 reactor = makereactor()
225 results = list(sendcommandframes(reactor, 1, b'mycommand',
242 stream = framing.stream()
243 results = list(sendcommandframes(reactor, stream, 1, b'mycommand',
226 244 {b'foo': b'bar', b'biz': b'baz'}))
227 245 self.assertEqual(len(results), 3)
228 246 self.assertaction(results[0], 'wantframe')
@@ -237,7 +255,8 b' class ServerReactorTests(unittest.TestCa'
237 255
238 256 def testsimplecommanddata(self):
239 257 reactor = makereactor()
240 results = list(sendcommandframes(reactor, 1, b'mycommand', {},
258 stream = framing.stream()
259 results = list(sendcommandframes(reactor, stream, 1, b'mycommand', {},
241 260 util.bytesio(b'data!')))
242 261 self.assertEqual(len(results), 2)
243 262 self.assertaction(results[0], 'wantframe')
@@ -350,19 +369,20 b' class ServerReactorTests(unittest.TestCa'
350 369 """Multiple fully serviced commands with same request ID is allowed."""
351 370 reactor = makereactor()
352 371 results = []
372 outstream = framing.stream()
353 373 results.append(self._sendsingleframe(
354 374 reactor, ffs(b'1 command-name eos command')))
355 result = reactor.onbytesresponseready(1, b'response1')
375 result = reactor.onbytesresponseready(outstream, 1, b'response1')
356 376 self.assertaction(result, 'sendframes')
357 377 list(result[1]['framegen'])
358 378 results.append(self._sendsingleframe(
359 379 reactor, ffs(b'1 command-name eos command')))
360 result = reactor.onbytesresponseready(1, b'response2')
380 result = reactor.onbytesresponseready(outstream, 1, b'response2')
361 381 self.assertaction(result, 'sendframes')
362 382 list(result[1]['framegen'])
363 383 results.append(self._sendsingleframe(
364 384 reactor, ffs(b'1 command-name eos command')))
365 result = reactor.onbytesresponseready(1, b'response3')
385 result = reactor.onbytesresponseready(outstream, 1, b'response3')
366 386 self.assertaction(result, 'sendframes')
367 387 list(result[1]['framegen'])
368 388
@@ -501,9 +521,11 b' class ServerReactorTests(unittest.TestCa'
501 521 def testsimpleresponse(self):
502 522 """Bytes response to command sends result frames."""
503 523 reactor = makereactor()
504 list(sendcommandframes(reactor, 1, b'mycommand', {}))
524 instream = framing.stream()
525 list(sendcommandframes(reactor, instream, 1, b'mycommand', {}))
505 526
506 result = reactor.onbytesresponseready(1, b'response')
527 outstream = framing.stream()
528 result = reactor.onbytesresponseready(outstream, 1, b'response')
507 529 self.assertaction(result, 'sendframes')
508 530 self.assertframesequal(result[1]['framegen'], [
509 531 b'1 bytes-response eos response',
@@ -515,9 +537,11 b' class ServerReactorTests(unittest.TestCa'
515 537 second = b'y' * 100
516 538
517 539 reactor = makereactor()
518 list(sendcommandframes(reactor, 1, b'mycommand', {}))
540 instream = framing.stream()
541 list(sendcommandframes(reactor, instream, 1, b'mycommand', {}))
519 542
520 result = reactor.onbytesresponseready(1, first + second)
543 outstream = framing.stream()
544 result = reactor.onbytesresponseready(outstream, 1, first + second)
521 545 self.assertaction(result, 'sendframes')
522 546 self.assertframesequal(result[1]['framegen'], [
523 547 b'1 bytes-response continuation %s' % first,
@@ -526,9 +550,11 b' class ServerReactorTests(unittest.TestCa'
526 550
527 551 def testapplicationerror(self):
528 552 reactor = makereactor()
529 list(sendcommandframes(reactor, 1, b'mycommand', {}))
553 instream = framing.stream()
554 list(sendcommandframes(reactor, instream, 1, b'mycommand', {}))
530 555
531 result = reactor.onapplicationerror(1, b'some message')
556 outstream = framing.stream()
557 result = reactor.onapplicationerror(outstream, 1, b'some message')
532 558 self.assertaction(result, 'sendframes')
533 559 self.assertframesequal(result[1]['framegen'], [
534 560 b'1 error-response application some message',
@@ -537,11 +563,14 b' class ServerReactorTests(unittest.TestCa'
537 563 def test1commanddeferresponse(self):
538 564 """Responses when in deferred output mode are delayed until EOF."""
539 565 reactor = makereactor(deferoutput=True)
540 results = list(sendcommandframes(reactor, 1, b'mycommand', {}))
566 instream = framing.stream()
567 results = list(sendcommandframes(reactor, instream, 1, b'mycommand',
568 {}))
541 569 self.assertEqual(len(results), 1)
542 570 self.assertaction(results[0], 'runcommand')
543 571
544 result = reactor.onbytesresponseready(1, b'response')
572 outstream = framing.stream()
573 result = reactor.onbytesresponseready(outstream, 1, b'response')
545 574 self.assertaction(result, 'noop')
546 575 result = reactor.oninputeof()
547 576 self.assertaction(result, 'sendframes')
@@ -551,12 +580,14 b' class ServerReactorTests(unittest.TestCa'
551 580
552 581 def testmultiplecommanddeferresponse(self):
553 582 reactor = makereactor(deferoutput=True)
554 list(sendcommandframes(reactor, 1, b'command1', {}))
555 list(sendcommandframes(reactor, 3, b'command2', {}))
583 instream = framing.stream()
584 list(sendcommandframes(reactor, instream, 1, b'command1', {}))
585 list(sendcommandframes(reactor, instream, 3, b'command2', {}))
556 586
557 result = reactor.onbytesresponseready(1, b'response1')
587 outstream = framing.stream()
588 result = reactor.onbytesresponseready(outstream, 1, b'response1')
558 589 self.assertaction(result, 'noop')
559 result = reactor.onbytesresponseready(3, b'response2')
590 result = reactor.onbytesresponseready(outstream, 3, b'response2')
560 591 self.assertaction(result, 'noop')
561 592 result = reactor.oninputeof()
562 593 self.assertaction(result, 'sendframes')
@@ -567,14 +598,16 b' class ServerReactorTests(unittest.TestCa'
567 598
568 599 def testrequestidtracking(self):
569 600 reactor = makereactor(deferoutput=True)
570 list(sendcommandframes(reactor, 1, b'command1', {}))
571 list(sendcommandframes(reactor, 3, b'command2', {}))
572 list(sendcommandframes(reactor, 5, b'command3', {}))
601 instream = framing.stream()
602 list(sendcommandframes(reactor, instream, 1, b'command1', {}))
603 list(sendcommandframes(reactor, instream, 3, b'command2', {}))
604 list(sendcommandframes(reactor, instream, 5, b'command3', {}))
573 605
574 606 # Register results for commands out of order.
575 reactor.onbytesresponseready(3, b'response3')
576 reactor.onbytesresponseready(1, b'response1')
577 reactor.onbytesresponseready(5, b'response5')
607 outstream = framing.stream()
608 reactor.onbytesresponseready(outstream, 3, b'response3')
609 reactor.onbytesresponseready(outstream, 1, b'response1')
610 reactor.onbytesresponseready(outstream, 5, b'response5')
578 611
579 612 result = reactor.oninputeof()
580 613 self.assertaction(result, 'sendframes')
@@ -587,8 +620,9 b' class ServerReactorTests(unittest.TestCa'
587 620 def testduplicaterequestonactivecommand(self):
588 621 """Receiving a request ID that matches a request that isn't finished."""
589 622 reactor = makereactor()
590 list(sendcommandframes(reactor, 1, b'command1', {}))
591 results = list(sendcommandframes(reactor, 1, b'command1', {}))
623 stream = framing.stream()
624 list(sendcommandframes(reactor, stream, 1, b'command1', {}))
625 results = list(sendcommandframes(reactor, stream, 1, b'command1', {}))
592 626
593 627 self.assertaction(results[0], 'error')
594 628 self.assertEqual(results[0][1], {
@@ -598,13 +632,15 b' class ServerReactorTests(unittest.TestCa'
598 632 def testduplicaterequestonactivecommandnosend(self):
599 633 """Same as above but we've registered a response but haven't sent it."""
600 634 reactor = makereactor()
601 list(sendcommandframes(reactor, 1, b'command1', {}))
602 reactor.onbytesresponseready(1, b'response')
635 instream = framing.stream()
636 list(sendcommandframes(reactor, instream, 1, b'command1', {}))
637 outstream = framing.stream()
638 reactor.onbytesresponseready(outstream, 1, b'response')
603 639
604 640 # We've registered the response but haven't sent it. From the
605 641 # perspective of the reactor, the command is still active.
606 642
607 results = list(sendcommandframes(reactor, 1, b'command1', {}))
643 results = list(sendcommandframes(reactor, instream, 1, b'command1', {}))
608 644 self.assertaction(results[0], 'error')
609 645 self.assertEqual(results[0][1], {
610 646 'message': b'request with ID 1 is already active',
@@ -613,7 +649,8 b' class ServerReactorTests(unittest.TestCa'
613 649 def testduplicaterequestargumentframe(self):
614 650 """Variant on above except we sent an argument frame instead of name."""
615 651 reactor = makereactor()
616 list(sendcommandframes(reactor, 1, b'command', {}))
652 stream = framing.stream()
653 list(sendcommandframes(reactor, stream, 1, b'command', {}))
617 654 results = list(sendframes(reactor, [
618 655 ffs(b'3 command-name have-args command'),
619 656 ffs(b'1 command-argument 0 ignored'),
@@ -627,11 +664,13 b' class ServerReactorTests(unittest.TestCa'
627 664 def testduplicaterequestaftersend(self):
628 665 """We can use a duplicate request ID after we've sent the response."""
629 666 reactor = makereactor()
630 list(sendcommandframes(reactor, 1, b'command1', {}))
631 res = reactor.onbytesresponseready(1, b'response')
667 instream = framing.stream()
668 list(sendcommandframes(reactor, instream, 1, b'command1', {}))
669 outstream = framing.stream()
670 res = reactor.onbytesresponseready(outstream, 1, b'response')
632 671 list(res[1]['framegen'])
633 672
634 results = list(sendcommandframes(reactor, 1, b'command1', {}))
673 results = list(sendcommandframes(reactor, instream, 1, b'command1', {}))
635 674 self.assertaction(results[0], 'runcommand')
636 675
637 676 if __name__ == '__main__':
General Comments 0
You need to be logged in to leave comments. Login now