Mercurial > hg
comparison tests/test-wireproto-serverreactor.py @ 37063:39304dd63589
wireproto: explicitly track which requests are active
We previously only tracked which requests are receiving. A
misbehaving client could accidentally have multiple requests with
the same ID in flight.
We now explicitly track which request IDs are currently active.
We make it illegal to receive a frame associated with a request
ID that has already been dispatched.
Differential Revision: https://phab.mercurial-scm.org/D2901
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Thu, 15 Mar 2018 18:05:49 -0700 |
parents | 884a0c1604ad |
children | 12bfc724217d |
comparison
equal
deleted
inserted
replaced
37062:fe4c944f95bb | 37063:39304dd63589 |
---|---|
476 def testframefornonreceivingrequest(self): | 476 def testframefornonreceivingrequest(self): |
477 """Receiving a frame for a command that is not receiving is illegal.""" | 477 """Receiving a frame for a command that is not receiving is illegal.""" |
478 results = list(sendframes(makereactor(), [ | 478 results = list(sendframes(makereactor(), [ |
479 ffs(b'1 command-name eos command1'), | 479 ffs(b'1 command-name eos command1'), |
480 ffs(b'3 command-name have-data command3'), | 480 ffs(b'3 command-name have-data command3'), |
481 ffs(b'1 command-argument eoa ignored'), | 481 ffs(b'5 command-argument eoa ignored'), |
482 ])) | 482 ])) |
483 self.assertaction(results[2], 'error') | 483 self.assertaction(results[2], 'error') |
484 self.assertEqual(results[2][1], { | 484 self.assertEqual(results[2][1], { |
485 'message': b'received frame for request that is not receiving: 1', | 485 'message': b'received frame for request that is not receiving: 5', |
486 }) | 486 }) |
487 | 487 |
488 def testsimpleresponse(self): | 488 def testsimpleresponse(self): |
489 """Bytes response to command sends result frames.""" | 489 """Bytes response to command sends result frames.""" |
490 reactor = makereactor() | 490 reactor = makereactor() |
569 b'3 bytes-response eos response3', | 569 b'3 bytes-response eos response3', |
570 b'1 bytes-response eos response1', | 570 b'1 bytes-response eos response1', |
571 b'5 bytes-response eos response5', | 571 b'5 bytes-response eos response5', |
572 ]) | 572 ]) |
573 | 573 |
574 def testduplicaterequestonactivecommand(self): | |
575 """Receiving a request ID that matches a request that isn't finished.""" | |
576 reactor = makereactor() | |
577 list(sendcommandframes(reactor, 1, b'command1', {})) | |
578 results = list(sendcommandframes(reactor, 1, b'command1', {})) | |
579 | |
580 self.assertaction(results[0], 'error') | |
581 self.assertEqual(results[0][1], { | |
582 'message': b'request with ID 1 is already active', | |
583 }) | |
584 | |
585 def testduplicaterequestonactivecommandnosend(self): | |
586 """Same as above but we've registered a response but haven't sent it.""" | |
587 reactor = makereactor() | |
588 list(sendcommandframes(reactor, 1, b'command1', {})) | |
589 reactor.onbytesresponseready(1, b'response') | |
590 | |
591 # We've registered the response but haven't sent it. From the | |
592 # perspective of the reactor, the command is still active. | |
593 | |
594 results = list(sendcommandframes(reactor, 1, b'command1', {})) | |
595 self.assertaction(results[0], 'error') | |
596 self.assertEqual(results[0][1], { | |
597 'message': b'request with ID 1 is already active', | |
598 }) | |
599 | |
600 def testduplicaterequestargumentframe(self): | |
601 """Variant on above except we sent an argument frame instead of name.""" | |
602 reactor = makereactor() | |
603 list(sendcommandframes(reactor, 1, b'command', {})) | |
604 results = list(sendframes(reactor, [ | |
605 ffs(b'3 command-name have-args command'), | |
606 ffs(b'1 command-argument 0 ignored'), | |
607 ])) | |
608 self.assertaction(results[0], 'wantframe') | |
609 self.assertaction(results[1], 'error') | |
610 self.assertEqual(results[1][1], { | |
611 'message': 'received frame for request that is still active: 1', | |
612 }) | |
613 | |
614 def testduplicaterequestaftersend(self): | |
615 """We can use a duplicate request ID after we've sent the response.""" | |
616 reactor = makereactor() | |
617 list(sendcommandframes(reactor, 1, b'command1', {})) | |
618 res = reactor.onbytesresponseready(1, b'response') | |
619 list(res[1]['framegen']) | |
620 | |
621 results = list(sendcommandframes(reactor, 1, b'command1', {})) | |
622 self.assertaction(results[0], 'runcommand') | |
623 | |
574 if __name__ == '__main__': | 624 if __name__ == '__main__': |
575 import silenttestrunner | 625 import silenttestrunner |
576 silenttestrunner.main(__name__) | 626 silenttestrunner.main(__name__) |