##// END OF EJS Templates
revisions: allow "x123" to refer to nodeid prefix "123"...
revisions: allow "x123" to refer to nodeid prefix "123" When resolving "123" to a revision, we try to interpret it as revnum before we try to interpret it as a nodeid hex prefix. This can lead to the shortest valid prefix being longer than necessary. This patch lets us write such nodeids in a shorter form by prefixing them with "x" instead of adding more hex digits until they're longer than the longest decimal revnum. On my hg repo with almost 69k revisions, turning this feature on saves on average 0.4% on the average nodeid length. That clearly doesn't justify this patch. However, it becomes more usefule when combined with the earlier patches in this series that let you disambiguate nodeid prefixes within a configured revset. Note that we attempt to resolve symbols as nodeid prefixes after we've exhausted all other posibilities, so this is a backwards compatible change (only queries that would previously fail may now succeed). I've still hidden this feature behind an experiemntal config option so we can roll it back if needed. Differential Revision: https://phab.mercurial-scm.org/D4041

File last commit:

r37742:deff7cf7 default
r38891:7848f284 default
Show More
test-wireproto-clientreactor.py
144 lines | 5.0 KiB | text/x-python | PythonLexer
/ tests / test-wireproto-clientreactor.py
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561 from __future__ import absolute_import
import unittest
from mercurial import (
error,
wireprotoframing as framing,
)
Gregory Szorc
wireproto: client reactor support for receiving frames...
r37562 ffs = framing.makeframefromhumanstring
def sendframe(reactor, frame):
"""Send a frame bytearray to a reactor."""
header = framing.parseheader(frame)
payload = frame[framing.FRAME_HEADER_SIZE:]
assert len(payload) == header.length
return reactor.onframerecv(framing.frame(header.requestid,
header.streamid,
header.streamflags,
header.typeid,
header.flags,
payload))
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561 class SingleSendTests(unittest.TestCase):
"""A reactor that can only send once rejects subsequent sends."""
Augie Fackler
cleanup: polyfill assertRaisesRegex so we can avoid assertRaisesRegexp...
r37733
if not getattr(unittest.TestCase, 'assertRaisesRegex', False):
# Python 3.7 deprecates the regex*p* version, but 2.7 lacks
# the regex version.
assertRaisesRegex = (# camelcase-required
unittest.TestCase.assertRaisesRegexp)
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561 def testbasic(self):
reactor = framing.clientreactor(hasmultiplesend=False, buffersends=True)
request, action, meta = reactor.callcommand(b'foo', {})
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(request.state, b'pending')
self.assertEqual(action, b'noop')
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561
action, meta = reactor.flushcommands()
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(action, b'sendframes')
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 for frame in meta[b'framegen']:
self.assertEqual(request.state, b'sending')
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(request.state, b'sent')
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561
Augie Fackler
cleanup: polyfill assertRaisesRegex so we can avoid assertRaisesRegexp...
r37733 with self.assertRaisesRegex(error.ProgrammingError,
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561 'cannot issue new commands'):
reactor.callcommand(b'foo', {})
Augie Fackler
cleanup: polyfill assertRaisesRegex so we can avoid assertRaisesRegexp...
r37733 with self.assertRaisesRegex(error.ProgrammingError,
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561 'cannot issue new commands'):
reactor.callcommand(b'foo', {})
class NoBufferTests(unittest.TestCase):
"""A reactor without send buffering sends requests immediately."""
def testbasic(self):
reactor = framing.clientreactor(hasmultiplesend=True, buffersends=False)
request, action, meta = reactor.callcommand(b'command1', {})
self.assertEqual(request.requestid, 1)
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(action, b'sendframes')
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(request.state, b'pending')
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 for frame in meta[b'framegen']:
self.assertEqual(request.state, b'sending')
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(request.state, b'sent')
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561
action, meta = reactor.flushcommands()
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(action, b'noop')
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561
# And we can send another command.
request, action, meta = reactor.callcommand(b'command2', {})
self.assertEqual(request.requestid, 3)
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(action, b'sendframes')
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 for frame in meta[b'framegen']:
self.assertEqual(request.state, b'sending')
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(request.state, b'sent')
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561
Gregory Szorc
wireproto: client reactor support for receiving frames...
r37562 class BadFrameRecvTests(unittest.TestCase):
Augie Fackler
cleanup: polyfill assertRaisesRegex so we can avoid assertRaisesRegexp...
r37733 if not getattr(unittest.TestCase, 'assertRaisesRegex', False):
# Python 3.7 deprecates the regex*p* version, but 2.7 lacks
# the regex version.
assertRaisesRegex = (# camelcase-required
unittest.TestCase.assertRaisesRegexp)
Gregory Szorc
wireproto: client reactor support for receiving frames...
r37562 def testoddstream(self):
reactor = framing.clientreactor()
action, meta = sendframe(reactor, ffs(b'1 1 0 1 0 foo'))
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(action, b'error')
self.assertEqual(meta[b'message'],
b'received frame with odd numbered stream ID: 1')
Gregory Szorc
wireproto: client reactor support for receiving frames...
r37562
def testunknownstream(self):
reactor = framing.clientreactor()
action, meta = sendframe(reactor, ffs(b'1 0 0 1 0 foo'))
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(action, b'error')
self.assertEqual(meta[b'message'],
b'received frame on unknown stream without beginning '
b'of stream flag set')
Gregory Szorc
wireproto: client reactor support for receiving frames...
r37562
def testunhandledframetype(self):
reactor = framing.clientreactor(buffersends=False)
request, action, meta = reactor.callcommand(b'foo', {})
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 for frame in meta[b'framegen']:
Gregory Szorc
wireproto: client reactor support for receiving frames...
r37562 pass
Augie Fackler
cleanup: polyfill assertRaisesRegex so we can avoid assertRaisesRegexp...
r37733 with self.assertRaisesRegex(error.ProgrammingError,
Gregory Szorc
wireproto: client reactor support for receiving frames...
r37562 'unhandled frame type'):
sendframe(reactor, ffs(b'1 0 stream-begin text-output 0 foo'))
Gregory Szorc
wireprotoframing: record when new stream is encountered...
r37674 class StreamTests(unittest.TestCase):
def testmultipleresponseframes(self):
reactor = framing.clientreactor(buffersends=False)
request, action, meta = reactor.callcommand(b'foo', {})
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(action, b'sendframes')
for f in meta[b'framegen']:
Gregory Szorc
wireprotoframing: record when new stream is encountered...
r37674 pass
action, meta = sendframe(
reactor,
Gregory Szorc
wireprotov2: change frame type and name for command response...
r37742 ffs(b'%d 0 stream-begin command-response 0 foo' %
request.requestid))
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(action, b'responsedata')
Gregory Szorc
wireprotoframing: record when new stream is encountered...
r37674
action, meta = sendframe(
reactor,
Gregory Szorc
wireprotov2: change frame type and name for command response...
r37742 ffs(b'%d 0 0 command-response eos bar' % request.requestid))
Augie Fackler
tests: add all missing b prefixes in reactor tests...
r37700 self.assertEqual(action, b'responsedata')
Gregory Szorc
wireprotoframing: record when new stream is encountered...
r37674
Gregory Szorc
wireproto: introduce a reactor for client-side state...
r37561 if __name__ == '__main__':
import silenttestrunner
silenttestrunner.main(__name__)