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, |
|
|
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, |
|
|
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( |
|
|
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, |
|
|
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, |
|
|
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, |
|
|
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, |
|
|
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, |
|
|
572 |
list(sendcommandframes(reactor, |
|
|
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( |
|
|
577 |
reactor.onbytesresponseready( |
|
|
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 |
|
|
|
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