exchangev2: remove it
As discussed on the mailing list, this is incomplete and unused with little
hope of revival.
Differential Revision: https://phab.mercurial-scm.org/D11954
--- a/mercurial/configitems.py Thu Dec 30 13:25:44 2021 +0100
+++ b/mercurial/configitems.py Tue Dec 07 16:44:22 2021 +0100
@@ -1102,16 +1102,6 @@
)
coreconfigitem(
b'experimental',
- b'httppeer.advertise-v2',
- default=False,
-)
-coreconfigitem(
- b'experimental',
- b'httppeer.v2-encoder-order',
- default=None,
-)
-coreconfigitem(
- b'experimental',
b'httppostargs',
default=False,
)
@@ -1211,11 +1201,6 @@
)
coreconfigitem(
b'experimental',
- b'sshserver.support-v2',
- default=False,
-)
-coreconfigitem(
- b'experimental',
b'sparse-read',
default=False,
)
@@ -1241,26 +1226,6 @@
)
coreconfigitem(
b'experimental',
- b'sshpeer.advertise-v2',
- default=False,
-)
-coreconfigitem(
- b'experimental',
- b'web.apiserver',
- default=False,
-)
-coreconfigitem(
- b'experimental',
- b'web.api.http-v2',
- default=False,
-)
-coreconfigitem(
- b'experimental',
- b'web.api.debugreflect',
- default=False,
-)
-coreconfigitem(
- b'experimental',
b'web.full-garbage-collection-rate',
default=1, # still forcing a full collection on each request
)
--- a/mercurial/debugcommands.py Thu Dec 30 13:25:44 2021 +0100
+++ b/mercurial/debugcommands.py Tue Dec 07 16:44:22 2021 +0100
@@ -91,7 +91,6 @@
vfs as vfsmod,
wireprotoframing,
wireprotoserver,
- wireprotov2peer,
)
from .interfaces import repository
from .utils import (
@@ -4352,8 +4351,8 @@
``--peer`` can be used to bypass the handshake protocol and construct a
peer instance using the specified class type. Valid values are ``raw``,
- ``http2``, ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending
- raw data payloads and don't support higher-level command actions.
+ ``ssh1``. ``raw`` instances only allow sending raw data payloads and
+ don't support higher-level command actions.
``--noreadstderr`` can be used to disable automatic reading from stderr
of the peer (for SSH connections only). Disabling automatic reading of
@@ -4528,13 +4527,11 @@
if opts[b'peer'] and opts[b'peer'] not in (
b'raw',
- b'http2',
b'ssh1',
- b'ssh2',
):
raise error.Abort(
_(b'invalid value for --peer'),
- hint=_(b'valid values are "raw", "ssh1", and "ssh2"'),
+ hint=_(b'valid values are "raw" and "ssh1"'),
)
if path and opts[b'localssh']:
@@ -4602,18 +4599,6 @@
None,
autoreadstderr=autoreadstderr,
)
- elif opts[b'peer'] == b'ssh2':
- ui.write(_(b'creating ssh peer for wire protocol version 2\n'))
- peer = sshpeer.sshv2peer(
- ui,
- url,
- proc,
- stdin,
- stdout,
- stderr,
- None,
- autoreadstderr=autoreadstderr,
- )
elif opts[b'peer'] == b'raw':
ui.write(_(b'using raw connection to peer\n'))
peer = None
@@ -4666,34 +4651,7 @@
opener = urlmod.opener(ui, authinfo, **openerargs)
- if opts[b'peer'] == b'http2':
- ui.write(_(b'creating http peer for wire protocol version 2\n'))
- # We go through makepeer() because we need an API descriptor for
- # the peer instance to be useful.
- maybe_silent = (
- ui.silent()
- if opts[b'nologhandshake']
- else util.nullcontextmanager()
- )
- with maybe_silent, ui.configoverride(
- {(b'experimental', b'httppeer.advertise-v2'): True}
- ):
- peer = httppeer.makepeer(ui, path, opener=opener)
-
- if not isinstance(peer, httppeer.httpv2peer):
- raise error.Abort(
- _(
- b'could not instantiate HTTP peer for '
- b'wire protocol version 2'
- ),
- hint=_(
- b'the server may not have the feature '
- b'enabled or is not allowing this '
- b'client version'
- ),
- )
-
- elif opts[b'peer'] == b'raw':
+ if opts[b'peer'] == b'raw':
ui.write(_(b'using raw connection to peer\n'))
peer = None
elif opts[b'peer']:
@@ -4774,17 +4732,10 @@
with peer.commandexecutor() as e:
res = e.callcommand(command, args).result()
- if isinstance(res, wireprotov2peer.commandresponse):
- val = res.objects()
- ui.status(
- _(b'response: %s\n')
- % stringutil.pprint(val, bprefix=True, indent=2)
- )
- else:
- ui.status(
- _(b'response: %s\n')
- % stringutil.pprint(res, bprefix=True, indent=2)
- )
+ ui.status(
+ _(b'response: %s\n')
+ % stringutil.pprint(res, bprefix=True, indent=2)
+ )
elif action == b'batchbegin':
if batchedcommands is not None:
--- a/mercurial/exchange.py Thu Dec 30 13:25:44 2021 +0100
+++ b/mercurial/exchange.py Tue Dec 07 16:44:22 2021 +0100
@@ -22,7 +22,6 @@
changegroup,
discovery,
error,
- exchangev2,
lock as lockmod,
logexchange,
narrowspec,
@@ -1666,21 +1665,17 @@
):
add_confirm_callback(repo, pullop)
- # Use the modern wire protocol, if available.
- if remote.capable(b'command-changesetdata'):
- exchangev2.pull(pullop)
- else:
- # This should ideally be in _pullbundle2(). However, it needs to run
- # before discovery to avoid extra work.
- _maybeapplyclonebundle(pullop)
- streamclone.maybeperformlegacystreamclone(pullop)
- _pulldiscovery(pullop)
- if pullop.canusebundle2:
- _fullpullbundle2(repo, pullop)
- _pullchangeset(pullop)
- _pullphase(pullop)
- _pullbookmarks(pullop)
- _pullobsolete(pullop)
+ # This should ideally be in _pullbundle2(). However, it needs to run
+ # before discovery to avoid extra work.
+ _maybeapplyclonebundle(pullop)
+ streamclone.maybeperformlegacystreamclone(pullop)
+ _pulldiscovery(pullop)
+ if pullop.canusebundle2:
+ _fullpullbundle2(repo, pullop)
+ _pullchangeset(pullop)
+ _pullphase(pullop)
+ _pullbookmarks(pullop)
+ _pullobsolete(pullop)
# storing remotenames
if repo.ui.configbool(b'experimental', b'remotenames'):
--- a/mercurial/exchangev2.py Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,804 +0,0 @@
-# exchangev2.py - repository exchange for wire protocol version 2
-#
-# Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-from __future__ import absolute_import
-
-import collections
-import weakref
-
-from .i18n import _
-from .node import short
-from . import (
- bookmarks,
- error,
- mdiff,
- narrowspec,
- phases,
- pycompat,
- requirements as requirementsmod,
- setdiscovery,
-)
-from .interfaces import repository
-
-
-def pull(pullop):
- """Pull using wire protocol version 2."""
- repo = pullop.repo
- remote = pullop.remote
-
- usingrawchangelogandmanifest = _checkuserawstorefiledata(pullop)
-
- # If this is a clone and it was requested to perform a "stream clone",
- # we obtain the raw files data from the remote then fall back to an
- # incremental pull. This is somewhat hacky and is not nearly robust enough
- # for long-term usage.
- if usingrawchangelogandmanifest:
- with repo.transaction(b'clone'):
- _fetchrawstorefiles(repo, remote)
- repo.invalidate(clearfilecache=True)
-
- tr = pullop.trmanager.transaction()
-
- # We don't use the repo's narrow matcher here because the patterns passed
- # to exchange.pull() could be different.
- narrowmatcher = narrowspec.match(
- repo.root,
- # Empty maps to nevermatcher. So always
- # set includes if missing.
- pullop.includepats or {b'path:.'},
- pullop.excludepats,
- )
-
- if pullop.includepats or pullop.excludepats:
- pathfilter = {}
- if pullop.includepats:
- pathfilter[b'include'] = sorted(pullop.includepats)
- if pullop.excludepats:
- pathfilter[b'exclude'] = sorted(pullop.excludepats)
- else:
- pathfilter = None
-
- # Figure out what needs to be fetched.
- common, fetch, remoteheads = _pullchangesetdiscovery(
- repo, remote, pullop.heads, abortwhenunrelated=pullop.force
- )
-
- # And fetch the data.
- pullheads = pullop.heads or remoteheads
- csetres = _fetchchangesets(repo, tr, remote, common, fetch, pullheads)
-
- # New revisions are written to the changelog. But all other updates
- # are deferred. Do those now.
-
- # Ensure all new changesets are draft by default. If the repo is
- # publishing, the phase will be adjusted by the loop below.
- if csetres[b'added']:
- phases.registernew(
- repo, tr, phases.draft, [repo[n].rev() for n in csetres[b'added']]
- )
-
- # And adjust the phase of all changesets accordingly.
- for phasenumber, phase in phases.phasenames.items():
- if phase == b'secret' or not csetres[b'nodesbyphase'][phase]:
- continue
-
- phases.advanceboundary(
- repo,
- tr,
- phasenumber,
- csetres[b'nodesbyphase'][phase],
- )
-
- # Write bookmark updates.
- bookmarks.updatefromremote(
- repo.ui,
- repo,
- csetres[b'bookmarks'],
- remote.url(),
- pullop.gettransaction,
- explicit=pullop.explicitbookmarks,
- )
-
- manres = _fetchmanifests(repo, tr, remote, csetres[b'manifestnodes'])
-
- # We don't properly support shallow changeset and manifest yet. So we apply
- # depth limiting locally.
- if pullop.depth:
- relevantcsetnodes = set()
- clnode = repo.changelog.node
-
- for rev in repo.revs(
- b'ancestors(%ln, %s)', pullheads, pullop.depth - 1
- ):
- relevantcsetnodes.add(clnode(rev))
-
- csetrelevantfilter = lambda n: n in relevantcsetnodes
-
- else:
- csetrelevantfilter = lambda n: True
-
- # If obtaining the raw store files, we need to scan the full repo to
- # derive all the changesets, manifests, and linkrevs.
- if usingrawchangelogandmanifest:
- csetsforfiles = []
- mnodesforfiles = []
- manifestlinkrevs = {}
-
- for rev in repo:
- ctx = repo[rev]
- node = ctx.node()
-
- if not csetrelevantfilter(node):
- continue
-
- mnode = ctx.manifestnode()
-
- csetsforfiles.append(node)
- mnodesforfiles.append(mnode)
- manifestlinkrevs[mnode] = rev
-
- else:
- csetsforfiles = [n for n in csetres[b'added'] if csetrelevantfilter(n)]
- mnodesforfiles = manres[b'added']
- manifestlinkrevs = manres[b'linkrevs']
-
- # Find all file nodes referenced by added manifests and fetch those
- # revisions.
- fnodes = _derivefilesfrommanifests(repo, narrowmatcher, mnodesforfiles)
- _fetchfilesfromcsets(
- repo,
- tr,
- remote,
- pathfilter,
- fnodes,
- csetsforfiles,
- manifestlinkrevs,
- shallow=bool(pullop.depth),
- )
-
-
-def _checkuserawstorefiledata(pullop):
- """Check whether we should use rawstorefiledata command to retrieve data."""
-
- repo = pullop.repo
- remote = pullop.remote
-
- # Command to obtain raw store data isn't available.
- if b'rawstorefiledata' not in remote.apidescriptor[b'commands']:
- return False
-
- # Only honor if user requested stream clone operation.
- if not pullop.streamclonerequested:
- return False
-
- # Only works on empty repos.
- if len(repo):
- return False
-
- # TODO This is super hacky. There needs to be a storage API for this. We
- # also need to check for compatibility with the remote.
- if requirementsmod.REVLOGV1_REQUIREMENT not in repo.requirements:
- return False
-
- return True
-
-
-def _fetchrawstorefiles(repo, remote):
- with remote.commandexecutor() as e:
- objs = e.callcommand(
- b'rawstorefiledata',
- {
- b'files': [b'changelog', b'manifestlog'],
- },
- ).result()
-
- # First object is a summary of files data that follows.
- overall = next(objs)
-
- progress = repo.ui.makeprogress(
- _(b'clone'), total=overall[b'totalsize'], unit=_(b'bytes')
- )
- with progress:
- progress.update(0)
-
- # Next are pairs of file metadata, data.
- while True:
- try:
- filemeta = next(objs)
- except StopIteration:
- break
-
- for k in (b'location', b'path', b'size'):
- if k not in filemeta:
- raise error.Abort(
- _(b'remote file data missing key: %s') % k
- )
-
- if filemeta[b'location'] == b'store':
- vfs = repo.svfs
- else:
- raise error.Abort(
- _(b'invalid location for raw file data: %s')
- % filemeta[b'location']
- )
-
- bytesremaining = filemeta[b'size']
-
- with vfs.open(filemeta[b'path'], b'wb') as fh:
- while True:
- try:
- chunk = next(objs)
- except StopIteration:
- break
-
- bytesremaining -= len(chunk)
-
- if bytesremaining < 0:
- raise error.Abort(
- _(
- b'received invalid number of bytes for file '
- b'data; expected %d, got extra'
- )
- % filemeta[b'size']
- )
-
- progress.increment(step=len(chunk))
- fh.write(chunk)
-
- try:
- if chunk.islast:
- break
- except AttributeError:
- raise error.Abort(
- _(
- b'did not receive indefinite length bytestring '
- b'for file data'
- )
- )
-
- if bytesremaining:
- raise error.Abort(
- _(
- b'received invalid number of bytes for'
- b'file data; expected %d got %d'
- )
- % (
- filemeta[b'size'],
- filemeta[b'size'] - bytesremaining,
- )
- )
-
-
-def _pullchangesetdiscovery(repo, remote, heads, abortwhenunrelated=True):
- """Determine which changesets need to be pulled."""
-
- if heads:
- knownnode = repo.changelog.hasnode
- if all(knownnode(head) for head in heads):
- return heads, False, heads
-
- # TODO wire protocol version 2 is capable of more efficient discovery
- # than setdiscovery. Consider implementing something better.
- common, fetch, remoteheads = setdiscovery.findcommonheads(
- repo.ui, repo, remote, abortwhenunrelated=abortwhenunrelated
- )
-
- common = set(common)
- remoteheads = set(remoteheads)
-
- # If a remote head is filtered locally, put it back in the common set.
- # See the comment in exchange._pulldiscoverychangegroup() for more.
-
- if fetch and remoteheads:
- has_node = repo.unfiltered().changelog.index.has_node
-
- common |= {head for head in remoteheads if has_node(head)}
-
- if set(remoteheads).issubset(common):
- fetch = []
-
- common.discard(repo.nullid)
-
- return common, fetch, remoteheads
-
-
-def _fetchchangesets(repo, tr, remote, common, fetch, remoteheads):
- # TODO consider adding a step here where we obtain the DAG shape first
- # (or ask the server to slice changesets into chunks for us) so that
- # we can perform multiple fetches in batches. This will facilitate
- # resuming interrupted clones, higher server-side cache hit rates due
- # to smaller segments, etc.
- with remote.commandexecutor() as e:
- objs = e.callcommand(
- b'changesetdata',
- {
- b'revisions': [
- {
- b'type': b'changesetdagrange',
- b'roots': sorted(common),
- b'heads': sorted(remoteheads),
- }
- ],
- b'fields': {b'bookmarks', b'parents', b'phase', b'revision'},
- },
- ).result()
-
- # The context manager waits on all response data when exiting. So
- # we need to remain in the context manager in order to stream data.
- return _processchangesetdata(repo, tr, objs)
-
-
-def _processchangesetdata(repo, tr, objs):
- repo.hook(b'prechangegroup', throw=True, **pycompat.strkwargs(tr.hookargs))
-
- urepo = repo.unfiltered()
- cl = urepo.changelog
-
- cl.delayupdate(tr)
-
- # The first emitted object is a header describing the data that
- # follows.
- meta = next(objs)
-
- progress = repo.ui.makeprogress(
- _(b'changesets'), unit=_(b'chunks'), total=meta.get(b'totalitems')
- )
-
- manifestnodes = {}
- added = []
-
- def linkrev(node):
- repo.ui.debug(b'add changeset %s\n' % short(node))
- # Linkrev for changelog is always self.
- return len(cl)
-
- def ondupchangeset(cl, rev):
- added.append(cl.node(rev))
-
- def onchangeset(cl, rev):
- progress.increment()
-
- revision = cl.changelogrevision(rev)
- added.append(cl.node(rev))
-
- # We need to preserve the mapping of changelog revision to node
- # so we can set the linkrev accordingly when manifests are added.
- manifestnodes[rev] = revision.manifest
-
- repo.register_changeset(rev, revision)
-
- nodesbyphase = {phase: set() for phase in phases.phasenames.values()}
- remotebookmarks = {}
-
- # addgroup() expects a 7-tuple describing revisions. This normalizes
- # the wire data to that format.
- #
- # This loop also aggregates non-revision metadata, such as phase
- # data.
- def iterrevisions():
- for cset in objs:
- node = cset[b'node']
-
- if b'phase' in cset:
- nodesbyphase[cset[b'phase']].add(node)
-
- for mark in cset.get(b'bookmarks', []):
- remotebookmarks[mark] = node
-
- # TODO add mechanism for extensions to examine records so they
- # can siphon off custom data fields.
-
- extrafields = {}
-
- for field, size in cset.get(b'fieldsfollowing', []):
- extrafields[field] = next(objs)
-
- # Some entries might only be metadata only updates.
- if b'revision' not in extrafields:
- continue
-
- data = extrafields[b'revision']
-
- yield (
- node,
- cset[b'parents'][0],
- cset[b'parents'][1],
- # Linknode is always itself for changesets.
- cset[b'node'],
- # We always send full revisions. So delta base is not set.
- repo.nullid,
- mdiff.trivialdiffheader(len(data)) + data,
- # Flags not yet supported.
- 0,
- # Sidedata not yet supported
- {},
- )
-
- cl.addgroup(
- iterrevisions(),
- linkrev,
- weakref.proxy(tr),
- alwayscache=True,
- addrevisioncb=onchangeset,
- duplicaterevisioncb=ondupchangeset,
- )
-
- progress.complete()
-
- return {
- b'added': added,
- b'nodesbyphase': nodesbyphase,
- b'bookmarks': remotebookmarks,
- b'manifestnodes': manifestnodes,
- }
-
-
-def _fetchmanifests(repo, tr, remote, manifestnodes):
- rootmanifest = repo.manifestlog.getstorage(b'')
-
- # Some manifests can be shared between changesets. Filter out revisions
- # we already know about.
- fetchnodes = []
- linkrevs = {}
- seen = set()
-
- for clrev, node in sorted(pycompat.iteritems(manifestnodes)):
- if node in seen:
- continue
-
- try:
- rootmanifest.rev(node)
- except error.LookupError:
- fetchnodes.append(node)
- linkrevs[node] = clrev
-
- seen.add(node)
-
- # TODO handle tree manifests
-
- # addgroup() expects 7-tuple describing revisions. This normalizes
- # the wire data to that format.
- def iterrevisions(objs, progress):
- for manifest in objs:
- node = manifest[b'node']
-
- extrafields = {}
-
- for field, size in manifest.get(b'fieldsfollowing', []):
- extrafields[field] = next(objs)
-
- if b'delta' in extrafields:
- basenode = manifest[b'deltabasenode']
- delta = extrafields[b'delta']
- elif b'revision' in extrafields:
- basenode = repo.nullid
- revision = extrafields[b'revision']
- delta = mdiff.trivialdiffheader(len(revision)) + revision
- else:
- continue
-
- yield (
- node,
- manifest[b'parents'][0],
- manifest[b'parents'][1],
- # The value passed in is passed to the lookup function passed
- # to addgroup(). We already have a map of manifest node to
- # changelog revision number. So we just pass in the
- # manifest node here and use linkrevs.__getitem__ as the
- # resolution function.
- node,
- basenode,
- delta,
- # Flags not yet supported.
- 0,
- # Sidedata not yet supported.
- {},
- )
-
- progress.increment()
-
- progress = repo.ui.makeprogress(
- _(b'manifests'), unit=_(b'chunks'), total=len(fetchnodes)
- )
-
- commandmeta = remote.apidescriptor[b'commands'][b'manifestdata']
- batchsize = commandmeta.get(b'recommendedbatchsize', 10000)
- # TODO make size configurable on client?
-
- # We send commands 1 at a time to the remote. This is not the most
- # efficient because we incur a round trip at the end of each batch.
- # However, the existing frame-based reactor keeps consuming server
- # data in the background. And this results in response data buffering
- # in memory. This can consume gigabytes of memory.
- # TODO send multiple commands in a request once background buffering
- # issues are resolved.
-
- added = []
-
- for i in pycompat.xrange(0, len(fetchnodes), batchsize):
- batch = [node for node in fetchnodes[i : i + batchsize]]
- if not batch:
- continue
-
- with remote.commandexecutor() as e:
- objs = e.callcommand(
- b'manifestdata',
- {
- b'tree': b'',
- b'nodes': batch,
- b'fields': {b'parents', b'revision'},
- b'haveparents': True,
- },
- ).result()
-
- # Chomp off header object.
- next(objs)
-
- def onchangeset(cl, rev):
- added.append(cl.node(rev))
-
- rootmanifest.addgroup(
- iterrevisions(objs, progress),
- linkrevs.__getitem__,
- weakref.proxy(tr),
- addrevisioncb=onchangeset,
- duplicaterevisioncb=onchangeset,
- )
-
- progress.complete()
-
- return {
- b'added': added,
- b'linkrevs': linkrevs,
- }
-
-
-def _derivefilesfrommanifests(repo, matcher, manifestnodes):
- """Determine what file nodes are relevant given a set of manifest nodes.
-
- Returns a dict mapping file paths to dicts of file node to first manifest
- node.
- """
- ml = repo.manifestlog
- fnodes = collections.defaultdict(dict)
-
- progress = repo.ui.makeprogress(
- _(b'scanning manifests'), total=len(manifestnodes)
- )
-
- with progress:
- for manifestnode in manifestnodes:
- m = ml.get(b'', manifestnode)
-
- # TODO this will pull in unwanted nodes because it takes the storage
- # delta into consideration. What we really want is something that
- # takes the delta between the manifest's parents. And ideally we
- # would ignore file nodes that are known locally. For now, ignore
- # both these limitations. This will result in incremental fetches
- # requesting data we already have. So this is far from ideal.
- md = m.readfast()
-
- for path, fnode in md.items():
- if matcher(path):
- fnodes[path].setdefault(fnode, manifestnode)
-
- progress.increment()
-
- return fnodes
-
-
-def _fetchfiles(repo, tr, remote, fnodes, linkrevs):
- """Fetch file data from explicit file revisions."""
-
- def iterrevisions(objs, progress):
- for filerevision in objs:
- node = filerevision[b'node']
-
- extrafields = {}
-
- for field, size in filerevision.get(b'fieldsfollowing', []):
- extrafields[field] = next(objs)
-
- if b'delta' in extrafields:
- basenode = filerevision[b'deltabasenode']
- delta = extrafields[b'delta']
- elif b'revision' in extrafields:
- basenode = repo.nullid
- revision = extrafields[b'revision']
- delta = mdiff.trivialdiffheader(len(revision)) + revision
- else:
- continue
-
- yield (
- node,
- filerevision[b'parents'][0],
- filerevision[b'parents'][1],
- node,
- basenode,
- delta,
- # Flags not yet supported.
- 0,
- # Sidedata not yet supported.
- {},
- )
-
- progress.increment()
-
- progress = repo.ui.makeprogress(
- _(b'files'),
- unit=_(b'chunks'),
- total=sum(len(v) for v in pycompat.itervalues(fnodes)),
- )
-
- # TODO make batch size configurable
- batchsize = 10000
- fnodeslist = [x for x in sorted(fnodes.items())]
-
- for i in pycompat.xrange(0, len(fnodeslist), batchsize):
- batch = [x for x in fnodeslist[i : i + batchsize]]
- if not batch:
- continue
-
- with remote.commandexecutor() as e:
- fs = []
- locallinkrevs = {}
-
- for path, nodes in batch:
- fs.append(
- (
- path,
- e.callcommand(
- b'filedata',
- {
- b'path': path,
- b'nodes': sorted(nodes),
- b'fields': {b'parents', b'revision'},
- b'haveparents': True,
- },
- ),
- )
- )
-
- locallinkrevs[path] = {
- node: linkrevs[manifestnode]
- for node, manifestnode in pycompat.iteritems(nodes)
- }
-
- for path, f in fs:
- objs = f.result()
-
- # Chomp off header objects.
- next(objs)
-
- store = repo.file(path)
- store.addgroup(
- iterrevisions(objs, progress),
- locallinkrevs[path].__getitem__,
- weakref.proxy(tr),
- )
-
-
-def _fetchfilesfromcsets(
- repo, tr, remote, pathfilter, fnodes, csets, manlinkrevs, shallow=False
-):
- """Fetch file data from explicit changeset revisions."""
-
- def iterrevisions(objs, remaining, progress):
- while remaining:
- filerevision = next(objs)
-
- node = filerevision[b'node']
-
- extrafields = {}
-
- for field, size in filerevision.get(b'fieldsfollowing', []):
- extrafields[field] = next(objs)
-
- if b'delta' in extrafields:
- basenode = filerevision[b'deltabasenode']
- delta = extrafields[b'delta']
- elif b'revision' in extrafields:
- basenode = repo.nullid
- revision = extrafields[b'revision']
- delta = mdiff.trivialdiffheader(len(revision)) + revision
- else:
- continue
-
- if b'linknode' in filerevision:
- linknode = filerevision[b'linknode']
- else:
- linknode = node
-
- yield (
- node,
- filerevision[b'parents'][0],
- filerevision[b'parents'][1],
- linknode,
- basenode,
- delta,
- # Flags not yet supported.
- 0,
- # Sidedata not yet supported.
- {},
- )
-
- progress.increment()
- remaining -= 1
-
- progress = repo.ui.makeprogress(
- _(b'files'),
- unit=_(b'chunks'),
- total=sum(len(v) for v in pycompat.itervalues(fnodes)),
- )
-
- commandmeta = remote.apidescriptor[b'commands'][b'filesdata']
- batchsize = commandmeta.get(b'recommendedbatchsize', 50000)
-
- shallowfiles = repository.REPO_FEATURE_SHALLOW_FILE_STORAGE in repo.features
- fields = {b'parents', b'revision'}
- clrev = repo.changelog.rev
-
- # There are no guarantees that we'll have ancestor revisions if
- # a) this repo has shallow file storage b) shallow data fetching is enabled.
- # Force remote to not delta against possibly unknown revisions when these
- # conditions hold.
- haveparents = not (shallowfiles or shallow)
-
- # Similarly, we may not have calculated linkrevs for all incoming file
- # revisions. Ask the remote to do work for us in this case.
- if not haveparents:
- fields.add(b'linknode')
-
- for i in pycompat.xrange(0, len(csets), batchsize):
- batch = [x for x in csets[i : i + batchsize]]
- if not batch:
- continue
-
- with remote.commandexecutor() as e:
- args = {
- b'revisions': [
- {
- b'type': b'changesetexplicit',
- b'nodes': batch,
- }
- ],
- b'fields': fields,
- b'haveparents': haveparents,
- }
-
- if pathfilter:
- args[b'pathfilter'] = pathfilter
-
- objs = e.callcommand(b'filesdata', args).result()
-
- # First object is an overall header.
- overall = next(objs)
-
- # We have overall['totalpaths'] segments.
- for i in pycompat.xrange(overall[b'totalpaths']):
- header = next(objs)
-
- path = header[b'path']
- store = repo.file(path)
-
- linkrevs = {
- fnode: manlinkrevs[mnode]
- for fnode, mnode in pycompat.iteritems(fnodes[path])
- }
-
- def getlinkrev(node):
- if node in linkrevs:
- return linkrevs[node]
- else:
- return clrev(node)
-
- store.addgroup(
- iterrevisions(objs, header[b'totalitems'], progress),
- getlinkrev,
- weakref.proxy(tr),
- maybemissingparents=shallow,
- )
--- a/mercurial/helptext/internals/wireprotocol.txt Thu Dec 30 13:25:44 2021 +0100
+++ b/mercurial/helptext/internals/wireprotocol.txt Tue Dec 07 16:44:22 2021 +0100
@@ -332,95 +332,6 @@
after responses. In other words, the length of the response contains the
trailing ``\n``.
-Clients supporting version 2 of the SSH transport send a line beginning
-with ``upgrade`` before the ``hello`` and ``between`` commands. The line
-(which isn't a well-formed command line because it doesn't consist of a
-single command name) serves to both communicate the client's intent to
-switch to transport version 2 (transports are version 1 by default) as
-well as to advertise the client's transport-level capabilities so the
-server may satisfy that request immediately.
-
-The upgrade line has the form:
-
- upgrade <token> <transport capabilities>
-
-That is the literal string ``upgrade`` followed by a space, followed by
-a randomly generated string, followed by a space, followed by a string
-denoting the client's transport capabilities.
-
-The token can be anything. However, a random UUID is recommended. (Use
-of version 4 UUIDs is recommended because version 1 UUIDs can leak the
-client's MAC address.)
-
-The transport capabilities string is a URL/percent encoded string
-containing key-value pairs defining the client's transport-level
-capabilities. The following capabilities are defined:
-
-proto
- A comma-delimited list of transport protocol versions the client
- supports. e.g. ``ssh-v2``.
-
-If the server does not recognize the ``upgrade`` line, it should issue
-an empty response and continue processing the ``hello`` and ``between``
-commands. Here is an example handshake between a version 2 aware client
-and a non version 2 aware server:
-
- c: upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=ssh-v2
- c: hello\n
- c: between\n
- c: pairs 81\n
- c: 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- s: 0\n
- s: 324\n
- s: capabilities: lookup changegroupsubset branchmap pushkey known getbundle ...\n
- s: 1\n
- s: \n
-
-(The initial ``0\n`` line from the server indicates an empty response to
-the unknown ``upgrade ..`` command/line.)
-
-If the server recognizes the ``upgrade`` line and is willing to satisfy that
-upgrade request, it replies to with a payload of the following form:
-
- upgraded <token> <transport name>\n
-
-This line is the literal string ``upgraded``, a space, the token that was
-specified by the client in its ``upgrade ...`` request line, a space, and the
-name of the transport protocol that was chosen by the server. The transport
-name MUST match one of the names the client specified in the ``proto`` field
-of its ``upgrade ...`` request line.
-
-If a server issues an ``upgraded`` response, it MUST also read and ignore
-the lines associated with the ``hello`` and ``between`` command requests
-that were issued by the server. It is assumed that the negotiated transport
-will respond with equivalent requested information following the transport
-handshake.
-
-All data following the ``\n`` terminating the ``upgraded`` line is the
-domain of the negotiated transport. It is common for the data immediately
-following to contain additional metadata about the state of the transport and
-the server. However, this isn't strictly speaking part of the transport
-handshake and isn't covered by this section.
-
-Here is an example handshake between a version 2 aware client and a version
-2 aware server:
-
- c: upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=ssh-v2
- c: hello\n
- c: between\n
- c: pairs 81\n
- c: 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- s: upgraded 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a ssh-v2\n
- s: <additional transport specific data>
-
-The client-issued token that is echoed in the response provides a more
-resilient mechanism for differentiating *banner* output from Mercurial
-output. In version 1, properly formatted banner output could get confused
-for Mercurial server output. By submitting a randomly generated token
-that is then present in the response, the client can look for that token
-in response lines and have reasonable certainty that the line did not
-originate from a *banner* message.
-
SSH Version 1 Transport
-----------------------
@@ -488,31 +399,6 @@
should issue a ``protocaps`` command after the initial handshake to annonunce
its own capabilities. The client capabilities are persistent.
-SSH Version 2 Transport
------------------------
-
-**Experimental and under development**
-
-Version 2 of the SSH transport behaves identically to version 1 of the SSH
-transport with the exception of handshake semantics. See above for how
-version 2 of the SSH transport is negotiated.
-
-Immediately following the ``upgraded`` line signaling a switch to version
-2 of the SSH protocol, the server automatically sends additional details
-about the capabilities of the remote server. This has the form:
-
- <integer length of value>\n
- capabilities: ...\n
-
-e.g.
-
- s: upgraded 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a ssh-v2\n
- s: 240\n
- s: capabilities: known getbundle batch ...\n
-
-Following capabilities advertisement, the peers communicate using version
-1 of the SSH transport.
-
Capabilities
============
--- a/mercurial/hgweb/hgweb_mod.py Thu Dec 30 13:25:44 2021 +0100
+++ b/mercurial/hgweb/hgweb_mod.py Tue Dec 07 16:44:22 2021 +0100
@@ -366,17 +366,6 @@
# replace it.
res.headers[b'Content-Security-Policy'] = rctx.csp
- # /api/* is reserved for various API implementations. Dispatch
- # accordingly. But URL paths can conflict with subrepos and virtual
- # repos in hgwebdir. So until we have a workaround for this, only
- # expose the URLs if the feature is enabled.
- apienabled = rctx.repo.ui.configbool(b'experimental', b'web.apiserver')
- if apienabled and req.dispatchparts and req.dispatchparts[0] == b'api':
- wireprotoserver.handlewsgiapirequest(
- rctx, req, res, self.check_perm
- )
- return res.sendresponse()
-
handled = wireprotoserver.handlewsgirequest(
rctx, req, res, self.check_perm
)
--- a/mercurial/httppeer.py Thu Dec 30 13:25:44 2021 +0100
+++ b/mercurial/httppeer.py Tue Dec 07 16:44:22 2021 +0100
@@ -13,7 +13,6 @@
import os
import socket
import struct
-import weakref
from .i18n import _
from .pycompat import getattr
@@ -25,21 +24,9 @@
statichttprepo,
url as urlmod,
util,
- wireprotoframing,
- wireprototypes,
wireprotov1peer,
- wireprotov2peer,
- wireprotov2server,
)
-from .interfaces import (
- repository,
- util as interfaceutil,
-)
-from .utils import (
- cborutil,
- stringutil,
- urlutil,
-)
+from .utils import urlutil
httplib = util.httplib
urlerr = util.urlerr
@@ -331,9 +318,7 @@
self.respurl = respurl
-def parsev1commandresponse(
- ui, baseurl, requrl, qs, resp, compressible, allowcbor=False
-):
+def parsev1commandresponse(ui, baseurl, requrl, qs, resp, compressible):
# record the url we got redirected to
redirected = False
respurl = pycompat.bytesurl(resp.geturl())
@@ -376,17 +361,6 @@
try:
subtype = proto.split(b'-', 1)[1]
- # Unless we end up supporting CBOR in the legacy wire protocol,
- # this should ONLY be encountered for the initial capabilities
- # request during handshake.
- if subtype == b'cbor':
- if allowcbor:
- return respurl, proto, resp
- else:
- raise error.RepoError(
- _(b'unexpected CBOR response from server')
- )
-
version_info = tuple([int(n) for n in subtype.split(b'.')])
except ValueError:
raise error.RepoError(
@@ -564,85 +538,6 @@
raise exception
-def sendv2request(
- ui, opener, requestbuilder, apiurl, permission, requests, redirect
-):
- wireprotoframing.populatestreamencoders()
-
- uiencoders = ui.configlist(b'experimental', b'httppeer.v2-encoder-order')
-
- if uiencoders:
- encoders = []
-
- for encoder in uiencoders:
- if encoder not in wireprotoframing.STREAM_ENCODERS:
- ui.warn(
- _(
- b'wire protocol version 2 encoder referenced in '
- b'config (%s) is not known; ignoring\n'
- )
- % encoder
- )
- else:
- encoders.append(encoder)
-
- else:
- encoders = wireprotoframing.STREAM_ENCODERS_ORDER
-
- reactor = wireprotoframing.clientreactor(
- ui,
- hasmultiplesend=False,
- buffersends=True,
- clientcontentencoders=encoders,
- )
-
- handler = wireprotov2peer.clienthandler(
- ui, reactor, opener=opener, requestbuilder=requestbuilder
- )
-
- url = b'%s/%s' % (apiurl, permission)
-
- if len(requests) > 1:
- url += b'/multirequest'
- else:
- url += b'/%s' % requests[0][0]
-
- ui.debug(b'sending %d commands\n' % len(requests))
- for command, args, f in requests:
- ui.debug(
- b'sending command %s: %s\n'
- % (command, stringutil.pprint(args, indent=2))
- )
- assert not list(
- handler.callcommand(command, args, f, redirect=redirect)
- )
-
- # TODO stream this.
- body = b''.join(map(bytes, handler.flushcommands()))
-
- # TODO modify user-agent to reflect v2
- headers = {
- 'Accept': wireprotov2server.FRAMINGTYPE,
- 'Content-Type': wireprotov2server.FRAMINGTYPE,
- }
-
- req = requestbuilder(pycompat.strurl(url), body, headers)
- req.add_unredirected_header('Content-Length', '%d' % len(body))
-
- try:
- res = opener.open(req)
- except urlerr.httperror as e:
- if e.code == 401:
- raise error.Abort(_(b'authorization failed'))
-
- raise
- except httplib.HTTPException as e:
- ui.traceback()
- raise IOError(None, e)
-
- return handler, res
-
-
class queuedcommandfuture(pycompat.futures.Future):
"""Wraps result() on command futures to trigger submission on call."""
@@ -657,302 +552,6 @@
return self.result(timeout)
-@interfaceutil.implementer(repository.ipeercommandexecutor)
-class httpv2executor(object):
- def __init__(
- self, ui, opener, requestbuilder, apiurl, descriptor, redirect
- ):
- self._ui = ui
- self._opener = opener
- self._requestbuilder = requestbuilder
- self._apiurl = apiurl
- self._descriptor = descriptor
- self._redirect = redirect
- self._sent = False
- self._closed = False
- self._neededpermissions = set()
- self._calls = []
- self._futures = weakref.WeakSet()
- self._responseexecutor = None
- self._responsef = None
-
- def __enter__(self):
- return self
-
- def __exit__(self, exctype, excvalue, exctb):
- self.close()
-
- def callcommand(self, command, args):
- if self._sent:
- raise error.ProgrammingError(
- b'callcommand() cannot be used after commands are sent'
- )
-
- if self._closed:
- raise error.ProgrammingError(
- b'callcommand() cannot be used after close()'
- )
-
- # The service advertises which commands are available. So if we attempt
- # to call an unknown command or pass an unknown argument, we can screen
- # for this.
- if command not in self._descriptor[b'commands']:
- raise error.ProgrammingError(
- b'wire protocol command %s is not available' % command
- )
-
- cmdinfo = self._descriptor[b'commands'][command]
- unknownargs = set(args.keys()) - set(cmdinfo.get(b'args', {}))
-
- if unknownargs:
- raise error.ProgrammingError(
- b'wire protocol command %s does not accept argument: %s'
- % (command, b', '.join(sorted(unknownargs)))
- )
-
- self._neededpermissions |= set(cmdinfo[b'permissions'])
-
- # TODO we /could/ also validate types here, since the API descriptor
- # includes types...
-
- f = pycompat.futures.Future()
-
- # Monkeypatch it so result() triggers sendcommands(), otherwise result()
- # could deadlock.
- f.__class__ = queuedcommandfuture
- f._peerexecutor = self
-
- self._futures.add(f)
- self._calls.append((command, args, f))
-
- return f
-
- def sendcommands(self):
- if self._sent:
- return
-
- if not self._calls:
- return
-
- self._sent = True
-
- # Unhack any future types so caller sees a clean type and so we
- # break reference cycle.
- for f in self._futures:
- if isinstance(f, queuedcommandfuture):
- f.__class__ = pycompat.futures.Future
- f._peerexecutor = None
-
- # Mark the future as running and filter out cancelled futures.
- calls = [
- (command, args, f)
- for command, args, f in self._calls
- if f.set_running_or_notify_cancel()
- ]
-
- # Clear out references, prevent improper object usage.
- self._calls = None
-
- if not calls:
- return
-
- permissions = set(self._neededpermissions)
-
- if b'push' in permissions and b'pull' in permissions:
- permissions.remove(b'pull')
-
- if len(permissions) > 1:
- raise error.RepoError(
- _(b'cannot make request requiring multiple permissions: %s')
- % _(b', ').join(sorted(permissions))
- )
-
- permission = {
- b'push': b'rw',
- b'pull': b'ro',
- }[permissions.pop()]
-
- handler, resp = sendv2request(
- self._ui,
- self._opener,
- self._requestbuilder,
- self._apiurl,
- permission,
- calls,
- self._redirect,
- )
-
- # TODO we probably want to validate the HTTP code, media type, etc.
-
- self._responseexecutor = pycompat.futures.ThreadPoolExecutor(1)
- self._responsef = self._responseexecutor.submit(
- self._handleresponse, handler, resp
- )
-
- def close(self):
- if self._closed:
- return
-
- self.sendcommands()
-
- self._closed = True
-
- if not self._responsef:
- return
-
- # TODO ^C here may not result in immediate program termination.
-
- try:
- self._responsef.result()
- finally:
- self._responseexecutor.shutdown(wait=True)
- self._responsef = None
- self._responseexecutor = None
-
- # If any of our futures are still in progress, mark them as
- # errored, otherwise a result() could wait indefinitely.
- for f in self._futures:
- if not f.done():
- f.set_exception(
- error.ResponseError(_(b'unfulfilled command response'))
- )
-
- self._futures = None
-
- def _handleresponse(self, handler, resp):
- # Called in a thread to read the response.
-
- while handler.readdata(resp):
- pass
-
-
-@interfaceutil.implementer(repository.ipeerv2)
-class httpv2peer(object):
-
- limitedarguments = False
-
- def __init__(
- self, ui, repourl, apipath, opener, requestbuilder, apidescriptor
- ):
- self.ui = ui
- self.apidescriptor = apidescriptor
-
- if repourl.endswith(b'/'):
- repourl = repourl[:-1]
-
- self._url = repourl
- self._apipath = apipath
- self._apiurl = b'%s/%s' % (repourl, apipath)
- self._opener = opener
- self._requestbuilder = requestbuilder
-
- self._redirect = wireprotov2peer.supportedredirects(ui, apidescriptor)
-
- # Start of ipeerconnection.
-
- def url(self):
- return self._url
-
- def local(self):
- return None
-
- def peer(self):
- return self
-
- def canpush(self):
- # TODO change once implemented.
- return False
-
- def close(self):
- self.ui.note(
- _(
- b'(sent %d HTTP requests and %d bytes; '
- b'received %d bytes in responses)\n'
- )
- % (
- self._opener.requestscount,
- self._opener.sentbytescount,
- self._opener.receivedbytescount,
- )
- )
-
- # End of ipeerconnection.
-
- # Start of ipeercapabilities.
-
- def capable(self, name):
- # The capabilities used internally historically map to capabilities
- # advertised from the "capabilities" wire protocol command. However,
- # version 2 of that command works differently.
-
- # Maps to commands that are available.
- if name in (
- b'branchmap',
- b'getbundle',
- b'known',
- b'lookup',
- b'pushkey',
- ):
- return True
-
- # Other concepts.
- if name in (b'bundle2',):
- return True
-
- # Alias command-* to presence of command of that name.
- if name.startswith(b'command-'):
- return name[len(b'command-') :] in self.apidescriptor[b'commands']
-
- return False
-
- def requirecap(self, name, purpose):
- if self.capable(name):
- return
-
- raise error.CapabilityError(
- _(
- b'cannot %s; client or remote repository does not support the '
- b'\'%s\' capability'
- )
- % (purpose, name)
- )
-
- # End of ipeercapabilities.
-
- def _call(self, name, **args):
- with self.commandexecutor() as e:
- return e.callcommand(name, args).result()
-
- def commandexecutor(self):
- return httpv2executor(
- self.ui,
- self._opener,
- self._requestbuilder,
- self._apiurl,
- self.apidescriptor,
- self._redirect,
- )
-
-
-# Registry of API service names to metadata about peers that handle it.
-#
-# The following keys are meaningful:
-#
-# init
-# Callable receiving (ui, repourl, servicepath, opener, requestbuilder,
-# apidescriptor) to create a peer.
-#
-# priority
-# Integer priority for the service. If we could choose from multiple
-# services, we choose the one with the highest priority.
-API_PEERS = {
- wireprototypes.HTTP_WIREPROTO_V2: {
- b'init': httpv2peer,
- b'priority': 50,
- },
-}
-
-
def performhandshake(ui, url, opener, requestbuilder):
# The handshake is a request to the capabilities command.
@@ -963,28 +562,6 @@
args = {}
- # The client advertises support for newer protocols by adding an
- # X-HgUpgrade-* header with a list of supported APIs and an
- # X-HgProto-* header advertising which serializing formats it supports.
- # We only support the HTTP version 2 transport and CBOR responses for
- # now.
- advertisev2 = ui.configbool(b'experimental', b'httppeer.advertise-v2')
-
- if advertisev2:
- args[b'headers'] = {
- 'X-HgProto-1': 'cbor',
- }
-
- args[b'headers'].update(
- encodevalueinheaders(
- b' '.join(sorted(API_PEERS)),
- b'X-HgUpgrade',
- # We don't know the header limit this early.
- # So make it small.
- 1024,
- )
- )
-
req, requrl, qs = makev1commandrequest(
ui, requestbuilder, caps, capable, url, b'capabilities', args
)
@@ -1004,7 +581,7 @@
# redirect that drops the query string to "just work."
try:
respurl, ct, resp = parsev1commandresponse(
- ui, url, requrl, qs, resp, compressible=False, allowcbor=advertisev2
+ ui, url, requrl, qs, resp, compressible=False
)
except RedirectedRepoError as e:
req, requrl, qs = makev1commandrequest(
@@ -1012,7 +589,7 @@
)
resp = sendrequest(ui, opener, req)
respurl, ct, resp = parsev1commandresponse(
- ui, url, requrl, qs, resp, compressible=False, allowcbor=advertisev2
+ ui, url, requrl, qs, resp, compressible=False
)
try:
@@ -1023,29 +600,7 @@
if not ct.startswith(b'application/mercurial-'):
raise error.ProgrammingError(b'unexpected content-type: %s' % ct)
- if advertisev2:
- if ct == b'application/mercurial-cbor':
- try:
- info = cborutil.decodeall(rawdata)[0]
- except cborutil.CBORDecodeError:
- raise error.Abort(
- _(b'error decoding CBOR from remote server'),
- hint=_(
- b'try again and consider contacting '
- b'the server operator'
- ),
- )
-
- # We got a legacy response. That's fine.
- elif ct in (b'application/mercurial-0.1', b'application/mercurial-0.2'):
- info = {b'v1capabilities': set(rawdata.split())}
-
- else:
- raise error.RepoError(
- _(b'unexpected response type from server: %s') % ct
- )
- else:
- info = {b'v1capabilities': set(rawdata.split())}
+ info = {b'v1capabilities': set(rawdata.split())}
return respurl, info
@@ -1073,29 +628,6 @@
respurl, info = performhandshake(ui, url, opener, requestbuilder)
- # Given the intersection of APIs that both we and the server support,
- # sort by their advertised priority and pick the first one.
- #
- # TODO consider making this request-based and interface driven. For
- # example, the caller could say "I want a peer that does X." It's quite
- # possible that not all peers would do that. Since we know the service
- # capabilities, we could filter out services not meeting the
- # requirements. Possibly by consulting the interfaces defined by the
- # peer type.
- apipeerchoices = set(info.get(b'apis', {}).keys()) & set(API_PEERS.keys())
-
- preferredchoices = sorted(
- apipeerchoices, key=lambda x: API_PEERS[x][b'priority'], reverse=True
- )
-
- for service in preferredchoices:
- apipath = b'%s/%s' % (info[b'apibase'].rstrip(b'/'), service)
-
- return API_PEERS[service][b'init'](
- ui, respurl, apipath, opener, requestbuilder, info[b'apis'][service]
- )
-
- # Failed to construct an API peer. Fall back to legacy.
return httppeer(
ui, path, respurl, opener, requestbuilder, info[b'v1capabilities']
)
--- a/mercurial/sshpeer.py Thu Dec 30 13:25:44 2021 +0100
+++ b/mercurial/sshpeer.py Tue Dec 07 16:44:22 2021 +0100
@@ -16,7 +16,6 @@
error,
pycompat,
util,
- wireprotoserver,
wireprototypes,
wireprotov1peer,
wireprotov1server,
@@ -288,10 +287,6 @@
# Generate a random token to help identify responses to version 2
# upgrade request.
token = pycompat.sysbytes(str(uuid.uuid4()))
- upgradecaps = [
- (b'proto', wireprotoserver.SSHV2),
- ]
- upgradecaps = util.urlreq.urlencode(upgradecaps)
try:
pairsarg = b'%s-%s' % (b'0' * 40, b'0' * 40)
@@ -302,11 +297,6 @@
pairsarg,
]
- # Request upgrade to version 2 if configured.
- if ui.configbool(b'experimental', b'sshpeer.advertise-v2'):
- ui.debug(b'sending upgrade request: %s %s\n' % (token, upgradecaps))
- handshake.insert(0, b'upgrade %s %s\n' % (token, upgradecaps))
-
if requestlog:
ui.debug(b'devel-peer-request: hello+between\n')
ui.debug(b'devel-peer-request: pairs: %d bytes\n' % len(pairsarg))
@@ -365,24 +355,6 @@
if l.startswith(b'capabilities:'):
caps.update(l[:-1].split(b':')[1].split())
break
- elif protoname == wireprotoserver.SSHV2:
- # We see a line with number of bytes to follow and then a value
- # looking like ``capabilities: *``.
- line = stdout.readline()
- try:
- valuelen = int(line)
- except ValueError:
- badresponse()
-
- capsline = stdout.read(valuelen)
- if not capsline.startswith(b'capabilities: '):
- badresponse()
-
- ui.debug(b'remote: %s\n' % capsline)
-
- caps.update(capsline.split(b':')[1].split())
- # Trailing newline.
- stdout.read(1)
# Error if we couldn't find capabilities, this means:
#
@@ -601,14 +573,6 @@
self._readerr()
-class sshv2peer(sshv1peer):
- """A peer that speakers version 2 of the transport protocol."""
-
- # Currently version 2 is identical to version 1 post handshake.
- # And handshake is performed before the peer is instantiated. So
- # we need no custom code.
-
-
def makepeer(ui, path, proc, stdin, stdout, stderr, autoreadstderr=True):
"""Make a peer instance from existing pipes.
@@ -640,17 +604,6 @@
caps,
autoreadstderr=autoreadstderr,
)
- elif protoname == wireprototypes.SSHV2:
- return sshv2peer(
- ui,
- path,
- proc,
- stdin,
- stdout,
- stderr,
- caps,
- autoreadstderr=autoreadstderr,
- )
else:
_cleanuppipes(ui, stdout, stdin, stderr, warn=None)
raise error.RepoError(
--- a/mercurial/wireprotoserver.py Thu Dec 30 13:25:44 2021 +0100
+++ b/mercurial/wireprotoserver.py Tue Dec 07 16:44:22 2021 +0100
@@ -18,11 +18,9 @@
util,
wireprototypes,
wireprotov1server,
- wireprotov2server,
)
from .interfaces import util as interfaceutil
from .utils import (
- cborutil,
compression,
stringutil,
)
@@ -39,7 +37,6 @@
HGERRTYPE = b'application/hg-error'
SSHV1 = wireprototypes.SSHV1
-SSHV2 = wireprototypes.SSHV2
def decodevaluefromheaders(req, headerprefix):
@@ -244,97 +241,6 @@
return True
-def _availableapis(repo):
- apis = set()
-
- # Registered APIs are made available via config options of the name of
- # the protocol.
- for k, v in API_HANDLERS.items():
- section, option = v[b'config'] # pytype: disable=attribute-error
- if repo.ui.configbool(section, option):
- apis.add(k)
-
- return apis
-
-
-def handlewsgiapirequest(rctx, req, res, checkperm):
- """Handle requests to /api/*."""
- assert req.dispatchparts[0] == b'api'
-
- repo = rctx.repo
-
- # This whole URL space is experimental for now. But we want to
- # reserve the URL space. So, 404 all URLs if the feature isn't enabled.
- if not repo.ui.configbool(b'experimental', b'web.apiserver'):
- res.status = b'404 Not Found'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_(b'Experimental API server endpoint not enabled'))
- return
-
- # The URL space is /api/<protocol>/*. The structure of URLs under varies
- # by <protocol>.
-
- availableapis = _availableapis(repo)
-
- # Requests to /api/ list available APIs.
- if req.dispatchparts == [b'api']:
- res.status = b'200 OK'
- res.headers[b'Content-Type'] = b'text/plain'
- lines = [
- _(
- b'APIs can be accessed at /api/<name>, where <name> can be '
- b'one of the following:\n'
- )
- ]
- if availableapis:
- lines.extend(sorted(availableapis))
- else:
- lines.append(_(b'(no available APIs)\n'))
- res.setbodybytes(b'\n'.join(lines))
- return
-
- proto = req.dispatchparts[1]
-
- if proto not in API_HANDLERS:
- res.status = b'404 Not Found'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(
- _(b'Unknown API: %s\nKnown APIs: %s')
- % (proto, b', '.join(sorted(availableapis)))
- )
- return
-
- if proto not in availableapis:
- res.status = b'404 Not Found'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_(b'API %s not enabled\n') % proto)
- return
-
- API_HANDLERS[proto][b'handler'](
- rctx, req, res, checkperm, req.dispatchparts[2:]
- )
-
-
-# Maps API name to metadata so custom API can be registered.
-# Keys are:
-#
-# config
-# Config option that controls whether service is enabled.
-# handler
-# Callable receiving (rctx, req, res, checkperm, urlparts) that is called
-# when a request to this API is received.
-# apidescriptor
-# Callable receiving (req, repo) that is called to obtain an API
-# descriptor for this service. The response must be serializable to CBOR.
-API_HANDLERS = {
- wireprotov2server.HTTP_WIREPROTO_V2: {
- b'config': (b'experimental', b'web.api.http-v2'),
- b'handler': wireprotov2server.handlehttpv2request,
- b'apidescriptor': wireprotov2server.httpv2apidescriptor,
- },
-}
-
-
def _httpresponsetype(ui, proto, prefer_uncompressed):
"""Determine the appropriate response type and compression settings.
@@ -371,55 +277,6 @@
return HGTYPE, util.compengines[b'zlib'], opts
-def processcapabilitieshandshake(repo, req, res, proto):
- """Called during a ?cmd=capabilities request.
-
- If the client is advertising support for a newer protocol, we send
- a CBOR response with information about available services. If no
- advertised services are available, we don't handle the request.
- """
- # Fall back to old behavior unless the API server is enabled.
- if not repo.ui.configbool(b'experimental', b'web.apiserver'):
- return False
-
- clientapis = decodevaluefromheaders(req, b'X-HgUpgrade')
- protocaps = decodevaluefromheaders(req, b'X-HgProto')
- if not clientapis or not protocaps:
- return False
-
- # We currently only support CBOR responses.
- protocaps = set(protocaps.split(b' '))
- if b'cbor' not in protocaps:
- return False
-
- descriptors = {}
-
- for api in sorted(set(clientapis.split()) & _availableapis(repo)):
- handler = API_HANDLERS[api]
-
- descriptorfn = handler.get(b'apidescriptor')
- if not descriptorfn:
- continue
-
- descriptors[api] = descriptorfn(req, repo)
-
- v1caps = wireprotov1server.dispatch(repo, proto, b'capabilities')
- assert isinstance(v1caps, wireprototypes.bytesresponse)
-
- m = {
- # TODO allow this to be configurable.
- b'apibase': b'api/',
- b'apis': descriptors,
- b'v1capabilities': v1caps.data,
- }
-
- res.status = b'200 OK'
- res.headers[b'Content-Type'] = b'application/mercurial-cbor'
- res.setbodybytes(b''.join(cborutil.streamencode(m)))
-
- return True
-
-
def _callhttp(repo, req, res, proto, cmd):
# Avoid cycle involving hg module.
from .hgweb import common as hgwebcommon
@@ -461,13 +318,6 @@
proto.checkperm(wireprotov1server.commands[cmd].permission)
- # Possibly handle a modern client wanting to switch protocols.
- if cmd == b'capabilities' and processcapabilitieshandshake(
- repo, req, res, proto
- ):
-
- return
-
rsp = wireprotov1server.dispatch(repo, proto, cmd)
if isinstance(rsp, bytes):
@@ -596,17 +446,6 @@
pass
-class sshv2protocolhandler(sshv1protocolhandler):
- """Protocol handler for version 2 of the SSH protocol."""
-
- @property
- def name(self):
- return wireprototypes.SSHV2
-
- def addcapabilities(self, repo, caps):
- return caps
-
-
def _runsshserver(ui, repo, fin, fout, ev):
# This function operates like a state machine of sorts. The following
# states are defined:
@@ -616,19 +455,6 @@
# new lines. These commands are processed in this state, one command
# after the other.
#
- # protov2-serving
- # Server is in protocol version 2 serving mode.
- #
- # upgrade-initial
- # The server is going to process an upgrade request.
- #
- # upgrade-v2-filter-legacy-handshake
- # The protocol is being upgraded to version 2. The server is expecting
- # the legacy handshake from version 1.
- #
- # upgrade-v2-finish
- # The upgrade to version 2 of the protocol is imminent.
- #
# shutdown
# The server is shutting down, possibly in reaction to a client event.
#
@@ -637,32 +463,9 @@
# protov1-serving -> shutdown
# When server receives an empty request or encounters another
# error.
- #
- # protov1-serving -> upgrade-initial
- # An upgrade request line was seen.
- #
- # upgrade-initial -> upgrade-v2-filter-legacy-handshake
- # Upgrade to version 2 in progress. Server is expecting to
- # process a legacy handshake.
- #
- # upgrade-v2-filter-legacy-handshake -> shutdown
- # Client did not fulfill upgrade handshake requirements.
- #
- # upgrade-v2-filter-legacy-handshake -> upgrade-v2-finish
- # Client fulfilled version 2 upgrade requirements. Finishing that
- # upgrade.
- #
- # upgrade-v2-finish -> protov2-serving
- # Protocol upgrade to version 2 complete. Server can now speak protocol
- # version 2.
- #
- # protov2-serving -> protov1-serving
- # Ths happens by default since protocol version 2 is the same as
- # version 1 except for the handshake.
state = b'protov1-serving'
proto = sshv1protocolhandler(ui, fin, fout)
- protoswitched = False
while not ev.is_set():
if state == b'protov1-serving':
@@ -674,21 +477,6 @@
state = b'shutdown'
continue
- # It looks like a protocol upgrade request. Transition state to
- # handle it.
- if request.startswith(b'upgrade '):
- if protoswitched:
- _sshv1respondooberror(
- fout,
- ui.ferr,
- b'cannot upgrade protocols multiple times',
- )
- state = b'shutdown'
- continue
-
- state = b'upgrade-initial'
- continue
-
available = wireprotov1server.commands.commandavailable(
request, proto
)
@@ -724,108 +512,6 @@
b'wire protocol command: %s' % rsp
)
- # For now, protocol version 2 serving just goes back to version 1.
- elif state == b'protov2-serving':
- state = b'protov1-serving'
- continue
-
- elif state == b'upgrade-initial':
- # We should never transition into this state if we've switched
- # protocols.
- assert not protoswitched
- assert proto.name == wireprototypes.SSHV1
-
- # Expected: upgrade <token> <capabilities>
- # If we get something else, the request is malformed. It could be
- # from a future client that has altered the upgrade line content.
- # We treat this as an unknown command.
- try:
- token, caps = request.split(b' ')[1:]
- except ValueError:
- _sshv1respondbytes(fout, b'')
- state = b'protov1-serving'
- continue
-
- # Send empty response if we don't support upgrading protocols.
- if not ui.configbool(b'experimental', b'sshserver.support-v2'):
- _sshv1respondbytes(fout, b'')
- state = b'protov1-serving'
- continue
-
- try:
- caps = urlreq.parseqs(caps)
- except ValueError:
- _sshv1respondbytes(fout, b'')
- state = b'protov1-serving'
- continue
-
- # We don't see an upgrade request to protocol version 2. Ignore
- # the upgrade request.
- wantedprotos = caps.get(b'proto', [b''])[0]
- if SSHV2 not in wantedprotos:
- _sshv1respondbytes(fout, b'')
- state = b'protov1-serving'
- continue
-
- # It looks like we can honor this upgrade request to protocol 2.
- # Filter the rest of the handshake protocol request lines.
- state = b'upgrade-v2-filter-legacy-handshake'
- continue
-
- elif state == b'upgrade-v2-filter-legacy-handshake':
- # Client should have sent legacy handshake after an ``upgrade``
- # request. Expected lines:
- #
- # hello
- # between
- # pairs 81
- # 0000...-0000...
-
- ok = True
- for line in (b'hello', b'between', b'pairs 81'):
- request = fin.readline()[:-1]
-
- if request != line:
- _sshv1respondooberror(
- fout,
- ui.ferr,
- b'malformed handshake protocol: missing %s' % line,
- )
- ok = False
- state = b'shutdown'
- break
-
- if not ok:
- continue
-
- request = fin.read(81)
- if request != b'%s-%s' % (b'0' * 40, b'0' * 40):
- _sshv1respondooberror(
- fout,
- ui.ferr,
- b'malformed handshake protocol: '
- b'missing between argument value',
- )
- state = b'shutdown'
- continue
-
- state = b'upgrade-v2-finish'
- continue
-
- elif state == b'upgrade-v2-finish':
- # Send the upgrade response.
- fout.write(b'upgraded %s %s\n' % (token, SSHV2))
- servercaps = wireprotov1server.capabilities(repo, proto)
- rsp = b'capabilities: %s' % servercaps.data
- fout.write(b'%d\n%s\n' % (len(rsp), rsp))
- fout.flush()
-
- proto = sshv2protocolhandler(ui, fin, fout)
- protoswitched = True
-
- state = b'protov2-serving'
- continue
-
elif state == b'shutdown':
break
--- a/mercurial/wireprototypes.py Thu Dec 30 13:25:44 2021 +0100
+++ b/mercurial/wireprototypes.py Tue Dec 07 16:44:22 2021 +0100
@@ -21,10 +21,6 @@
# Names of the SSH protocol implementations.
SSHV1 = b'ssh-v1'
-# These are advertised over the wire. Increment the counters at the end
-# to reflect BC breakages.
-SSHV2 = b'exp-ssh-v2-0003'
-HTTP_WIREPROTO_V2 = b'exp-http-v2-0003'
NARROWCAP = b'exp-narrow-1'
ELLIPSESCAP1 = b'exp-ellipses-1'
@@ -37,19 +33,10 @@
b'transport': b'ssh',
b'version': 1,
},
- SSHV2: {
- b'transport': b'ssh',
- # TODO mark as version 2 once all commands are implemented.
- b'version': 1,
- },
b'http-v1': {
b'transport': b'http',
b'version': 1,
},
- HTTP_WIREPROTO_V2: {
- b'transport': b'http',
- b'version': 2,
- },
}
--- a/mercurial/wireprotov1server.py Thu Dec 30 13:25:44 2021 +0100
+++ b/mercurial/wireprotov1server.py Tue Dec 07 16:44:22 2021 +0100
@@ -147,12 +147,6 @@
k for k, v in wireprototypes.TRANSPORTS.items() if v[b'version'] == 1
}
- # Because SSHv2 is a mirror of SSHv1, we allow "batch" commands through to
- # SSHv2.
- # TODO undo this hack when SSH is using the unified frame protocol.
- if name == b'batch':
- transports.add(wireprototypes.SSHV2)
-
if permission not in (b'push', b'pull'):
raise error.ProgrammingError(
b'invalid wire protocol permission; '
--- a/mercurial/wireprotov2peer.py Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,576 +0,0 @@
-# wireprotov2peer.py - client side code for wire protocol version 2
-#
-# Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-from __future__ import absolute_import
-
-import threading
-
-from .i18n import _
-from . import (
- encoding,
- error,
- pycompat,
- sslutil,
- url as urlmod,
- util,
- wireprotoframing,
- wireprototypes,
-)
-from .utils import cborutil
-
-
-def formatrichmessage(atoms):
- """Format an encoded message from the framing protocol."""
-
- chunks = []
-
- for atom in atoms:
- msg = _(atom[b'msg'])
-
- if b'args' in atom:
- msg = msg % tuple(atom[b'args'])
-
- chunks.append(msg)
-
- return b''.join(chunks)
-
-
-SUPPORTED_REDIRECT_PROTOCOLS = {
- b'http',
- b'https',
-}
-
-SUPPORTED_CONTENT_HASHES = {
- b'sha1',
- b'sha256',
-}
-
-
-def redirecttargetsupported(ui, target):
- """Determine whether a redirect target entry is supported.
-
- ``target`` should come from the capabilities data structure emitted by
- the server.
- """
- if target.get(b'protocol') not in SUPPORTED_REDIRECT_PROTOCOLS:
- ui.note(
- _(b'(remote redirect target %s uses unsupported protocol: %s)\n')
- % (target[b'name'], target.get(b'protocol', b''))
- )
- return False
-
- if target.get(b'snirequired') and not sslutil.hassni:
- ui.note(
- _(b'(redirect target %s requires SNI, which is unsupported)\n')
- % target[b'name']
- )
- return False
-
- if b'tlsversions' in target:
- tlsversions = set(target[b'tlsversions'])
- supported = set()
-
- for v in sslutil.supportedprotocols:
- assert v.startswith(b'tls')
- supported.add(v[3:])
-
- if not tlsversions & supported:
- ui.note(
- _(
- b'(remote redirect target %s requires unsupported TLS '
- b'versions: %s)\n'
- )
- % (target[b'name'], b', '.join(sorted(tlsversions)))
- )
- return False
-
- ui.note(_(b'(remote redirect target %s is compatible)\n') % target[b'name'])
-
- return True
-
-
-def supportedredirects(ui, apidescriptor):
- """Resolve the "redirect" command request key given an API descriptor.
-
- Given an API descriptor returned by the server, returns a data structure
- that can be used in hte "redirect" field of command requests to advertise
- support for compatible redirect targets.
-
- Returns None if no redirect targets are remotely advertised or if none are
- supported.
- """
- if not apidescriptor or b'redirect' not in apidescriptor:
- return None
-
- targets = [
- t[b'name']
- for t in apidescriptor[b'redirect'][b'targets']
- if redirecttargetsupported(ui, t)
- ]
-
- hashes = [
- h
- for h in apidescriptor[b'redirect'][b'hashes']
- if h in SUPPORTED_CONTENT_HASHES
- ]
-
- return {
- b'targets': targets,
- b'hashes': hashes,
- }
-
-
-class commandresponse(object):
- """Represents the response to a command request.
-
- Instances track the state of the command and hold its results.
-
- An external entity is required to update the state of the object when
- events occur.
- """
-
- def __init__(self, requestid, command, fromredirect=False):
- self.requestid = requestid
- self.command = command
- self.fromredirect = fromredirect
-
- # Whether all remote input related to this command has been
- # received.
- self._inputcomplete = False
-
- # We have a lock that is acquired when important object state is
- # mutated. This is to prevent race conditions between 1 thread
- # sending us new data and another consuming it.
- self._lock = threading.RLock()
-
- # An event is set when state of the object changes. This event
- # is waited on by the generator emitting objects.
- self._serviceable = threading.Event()
-
- self._pendingevents = []
- self._pendingerror = None
- self._decoder = cborutil.bufferingdecoder()
- self._seeninitial = False
- self._redirect = None
-
- def _oninputcomplete(self):
- with self._lock:
- self._inputcomplete = True
- self._serviceable.set()
-
- def _onresponsedata(self, data):
- available, readcount, wanted = self._decoder.decode(data)
-
- if not available:
- return
-
- with self._lock:
- for o in self._decoder.getavailable():
- if not self._seeninitial and not self.fromredirect:
- self._handleinitial(o)
- continue
-
- # We should never see an object after a content redirect,
- # as the spec says the main status object containing the
- # content redirect is the only object in the stream. Fail
- # if we see a misbehaving server.
- if self._redirect:
- raise error.Abort(
- _(
- b'received unexpected response data '
- b'after content redirect; the remote is '
- b'buggy'
- )
- )
-
- self._pendingevents.append(o)
-
- self._serviceable.set()
-
- def _onerror(self, e):
- self._pendingerror = e
-
- with self._lock:
- self._serviceable.set()
-
- def _handleinitial(self, o):
- self._seeninitial = True
- if o[b'status'] == b'ok':
- return
-
- elif o[b'status'] == b'redirect':
- l = o[b'location']
- self._redirect = wireprototypes.alternatelocationresponse(
- url=l[b'url'],
- mediatype=l[b'mediatype'],
- size=l.get(b'size'),
- fullhashes=l.get(b'fullhashes'),
- fullhashseed=l.get(b'fullhashseed'),
- serverdercerts=l.get(b'serverdercerts'),
- servercadercerts=l.get(b'servercadercerts'),
- )
- return
-
- atoms = [{b'msg': o[b'error'][b'message']}]
- if b'args' in o[b'error']:
- atoms[0][b'args'] = o[b'error'][b'args']
-
- raise error.RepoError(formatrichmessage(atoms))
-
- def objects(self):
- """Obtained decoded objects from this response.
-
- This is a generator of data structures that were decoded from the
- command response.
-
- Obtaining the next member of the generator may block due to waiting
- on external data to become available.
-
- If the server encountered an error in the middle of serving the data
- or if another error occurred, an exception may be raised when
- advancing the generator.
- """
- while True:
- # TODO this can infinite loop if self._inputcomplete is never
- # set. We likely want to tie the lifetime of this object/state
- # to that of the background thread receiving frames and updating
- # our state.
- self._serviceable.wait(1.0)
-
- if self._pendingerror:
- raise self._pendingerror
-
- with self._lock:
- self._serviceable.clear()
-
- # Make copies because objects could be mutated during
- # iteration.
- stop = self._inputcomplete
- pending = list(self._pendingevents)
- self._pendingevents[:] = []
-
- for o in pending:
- yield o
-
- if stop:
- break
-
-
-class clienthandler(object):
- """Object to handle higher-level client activities.
-
- The ``clientreactor`` is used to hold low-level state about the frame-based
- protocol, such as which requests and streams are active. This type is used
- for higher-level operations, such as reading frames from a socket, exposing
- and managing a higher-level primitive for representing command responses,
- etc. This class is what peers should probably use to bridge wire activity
- with the higher-level peer API.
- """
-
- def __init__(
- self, ui, clientreactor, opener=None, requestbuilder=util.urlreq.request
- ):
- self._ui = ui
- self._reactor = clientreactor
- self._requests = {}
- self._futures = {}
- self._responses = {}
- self._redirects = []
- self._frameseof = False
- self._opener = opener or urlmod.opener(ui)
- self._requestbuilder = requestbuilder
-
- def callcommand(self, command, args, f, redirect=None):
- """Register a request to call a command.
-
- Returns an iterable of frames that should be sent over the wire.
- """
- request, action, meta = self._reactor.callcommand(
- command, args, redirect=redirect
- )
-
- if action != b'noop':
- raise error.ProgrammingError(b'%s not yet supported' % action)
-
- rid = request.requestid
- self._requests[rid] = request
- self._futures[rid] = f
- # TODO we need some kind of lifetime on response instances otherwise
- # objects() may deadlock.
- self._responses[rid] = commandresponse(rid, command)
-
- return iter(())
-
- def flushcommands(self):
- """Flush all queued commands.
-
- Returns an iterable of frames that should be sent over the wire.
- """
- action, meta = self._reactor.flushcommands()
-
- if action != b'sendframes':
- raise error.ProgrammingError(b'%s not yet supported' % action)
-
- return meta[b'framegen']
-
- def readdata(self, framefh):
- """Attempt to read data and do work.
-
- Returns None if no data was read. Presumably this means we're
- done with all read I/O.
- """
- if not self._frameseof:
- frame = wireprotoframing.readframe(framefh)
- if frame is None:
- # TODO tell reactor?
- self._frameseof = True
- else:
- self._ui.debug(b'received %r\n' % frame)
- self._processframe(frame)
-
- # Also try to read the first redirect.
- if self._redirects:
- if not self._processredirect(*self._redirects[0]):
- self._redirects.pop(0)
-
- if self._frameseof and not self._redirects:
- return None
-
- return True
-
- def _processframe(self, frame):
- """Process a single read frame."""
-
- action, meta = self._reactor.onframerecv(frame)
-
- if action == b'error':
- e = error.RepoError(meta[b'message'])
-
- if frame.requestid in self._responses:
- self._responses[frame.requestid]._oninputcomplete()
-
- if frame.requestid in self._futures:
- self._futures[frame.requestid].set_exception(e)
- del self._futures[frame.requestid]
- else:
- raise e
-
- return
- elif action == b'noop':
- return
- elif action == b'responsedata':
- # Handled below.
- pass
- else:
- raise error.ProgrammingError(b'action not handled: %s' % action)
-
- if frame.requestid not in self._requests:
- raise error.ProgrammingError(
- b'received frame for unknown request; this is either a bug in '
- b'the clientreactor not screening for this or this instance was '
- b'never told about this request: %r' % frame
- )
-
- response = self._responses[frame.requestid]
-
- if action == b'responsedata':
- # Any failures processing this frame should bubble up to the
- # future tracking the request.
- try:
- self._processresponsedata(frame, meta, response)
- except BaseException as e:
- # If an exception occurs before the future is resolved,
- # fail the future. Otherwise, we stuff the exception on
- # the response object so it can be raised during objects()
- # iteration. If nothing is consuming objects(), we could
- # silently swallow this exception. That's a risk we'll have to
- # take.
- if frame.requestid in self._futures:
- self._futures[frame.requestid].set_exception(e)
- del self._futures[frame.requestid]
- response._oninputcomplete()
- else:
- response._onerror(e)
- else:
- raise error.ProgrammingError(
- b'unhandled action from clientreactor: %s' % action
- )
-
- def _processresponsedata(self, frame, meta, response):
- # This can raise. The caller can handle it.
- response._onresponsedata(meta[b'data'])
-
- # We need to be careful about resolving futures prematurely. If a
- # response is a redirect response, resolving the future before the
- # redirect is processed would result in the consumer seeing an
- # empty stream of objects, since they'd be consuming our
- # response.objects() instead of the redirect's response.objects().
- #
- # Our strategy is to not resolve/finish the request until either
- # EOS occurs or until the initial response object is fully received.
-
- # Always react to eos.
- if meta[b'eos']:
- response._oninputcomplete()
- del self._requests[frame.requestid]
-
- # Not EOS but we haven't decoded the initial response object yet.
- # Return and wait for more data.
- elif not response._seeninitial:
- return
-
- # The specification says no objects should follow the initial/redirect
- # object. So it should be safe to handle the redirect object if one is
- # decoded, without having to wait for EOS.
- if response._redirect:
- self._followredirect(frame.requestid, response._redirect)
- return
-
- # If the command has a decoder, we wait until all input has been
- # received before resolving the future. Otherwise we resolve the
- # future immediately.
- if frame.requestid not in self._futures:
- return
-
- if response.command not in COMMAND_DECODERS:
- self._futures[frame.requestid].set_result(response.objects())
- del self._futures[frame.requestid]
- elif response._inputcomplete:
- decoded = COMMAND_DECODERS[response.command](response.objects())
- self._futures[frame.requestid].set_result(decoded)
- del self._futures[frame.requestid]
-
- def _followredirect(self, requestid, redirect):
- """Called to initiate redirect following for a request."""
- self._ui.note(_(b'(following redirect to %s)\n') % redirect.url)
-
- # TODO handle framed responses.
- if redirect.mediatype != b'application/mercurial-cbor':
- raise error.Abort(
- _(b'cannot handle redirects for the %s media type')
- % redirect.mediatype
- )
-
- if redirect.fullhashes:
- self._ui.warn(
- _(
- b'(support for validating hashes on content '
- b'redirects not supported)\n'
- )
- )
-
- if redirect.serverdercerts or redirect.servercadercerts:
- self._ui.warn(
- _(
- b'(support for pinning server certificates on '
- b'content redirects not supported)\n'
- )
- )
-
- headers = {
- 'Accept': redirect.mediatype,
- }
-
- req = self._requestbuilder(pycompat.strurl(redirect.url), None, headers)
-
- try:
- res = self._opener.open(req)
- except util.urlerr.httperror as e:
- if e.code == 401:
- raise error.Abort(_(b'authorization failed'))
- raise
- except util.httplib.HTTPException as e:
- self._ui.debug(b'http error requesting %s\n' % req.get_full_url())
- self._ui.traceback()
- raise IOError(None, e)
-
- urlmod.wrapresponse(res)
-
- # The existing response object is associated with frame data. Rather
- # than try to normalize its state, just create a new object.
- oldresponse = self._responses[requestid]
- self._responses[requestid] = commandresponse(
- requestid, oldresponse.command, fromredirect=True
- )
-
- self._redirects.append((requestid, res))
-
- def _processredirect(self, rid, res):
- """Called to continue processing a response from a redirect.
-
- Returns a bool indicating if the redirect is still serviceable.
- """
- response = self._responses[rid]
-
- try:
- data = res.read(32768)
- response._onresponsedata(data)
-
- # We're at end of stream.
- if not data:
- response._oninputcomplete()
-
- if rid not in self._futures:
- return bool(data)
-
- if response.command not in COMMAND_DECODERS:
- self._futures[rid].set_result(response.objects())
- del self._futures[rid]
- elif response._inputcomplete:
- decoded = COMMAND_DECODERS[response.command](response.objects())
- self._futures[rid].set_result(decoded)
- del self._futures[rid]
-
- return bool(data)
-
- except BaseException as e:
- self._futures[rid].set_exception(e)
- del self._futures[rid]
- response._oninputcomplete()
- return False
-
-
-def decodebranchmap(objs):
- # Response should be a single CBOR map of branch name to array of nodes.
- bm = next(objs)
-
- return {encoding.tolocal(k): v for k, v in bm.items()}
-
-
-def decodeheads(objs):
- # Array of node bytestrings.
- return next(objs)
-
-
-def decodeknown(objs):
- # Bytestring where each byte is a 0 or 1.
- raw = next(objs)
-
- return [True if raw[i : i + 1] == b'1' else False for i in range(len(raw))]
-
-
-def decodelistkeys(objs):
- # Map with bytestring keys and values.
- return next(objs)
-
-
-def decodelookup(objs):
- return next(objs)
-
-
-def decodepushkey(objs):
- return next(objs)
-
-
-COMMAND_DECODERS = {
- b'branchmap': decodebranchmap,
- b'heads': decodeheads,
- b'known': decodeknown,
- b'listkeys': decodelistkeys,
- b'lookup': decodelookup,
- b'pushkey': decodepushkey,
-}
--- a/mercurial/wireprotov2server.py Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1617 +0,0 @@
-# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
-# Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-from __future__ import absolute_import
-
-import collections
-import contextlib
-
-from .i18n import _
-from .node import hex
-from . import (
- discovery,
- encoding,
- error,
- match as matchmod,
- narrowspec,
- pycompat,
- streamclone,
- templatefilters,
- util,
- wireprotoframing,
- wireprototypes,
-)
-from .interfaces import util as interfaceutil
-from .utils import (
- cborutil,
- hashutil,
- stringutil,
-)
-
-FRAMINGTYPE = b'application/mercurial-exp-framing-0006'
-
-HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2
-
-COMMANDS = wireprototypes.commanddict()
-
-# Value inserted into cache key computation function. Change the value to
-# force new cache keys for every command request. This should be done when
-# there is a change to how caching works, etc.
-GLOBAL_CACHE_VERSION = 1
-
-
-def handlehttpv2request(rctx, req, res, checkperm, urlparts):
- from .hgweb import common as hgwebcommon
-
- # URL space looks like: <permissions>/<command>, where <permission> can
- # be ``ro`` or ``rw`` to signal read-only or read-write, respectively.
-
- # Root URL does nothing meaningful... yet.
- if not urlparts:
- res.status = b'200 OK'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_(b'HTTP version 2 API handler'))
- return
-
- if len(urlparts) == 1:
- res.status = b'404 Not Found'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(
- _(b'do not know how to process %s\n') % req.dispatchpath
- )
- return
-
- permission, command = urlparts[0:2]
-
- if permission not in (b'ro', b'rw'):
- res.status = b'404 Not Found'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_(b'unknown permission: %s') % permission)
- return
-
- if req.method != b'POST':
- res.status = b'405 Method Not Allowed'
- res.headers[b'Allow'] = b'POST'
- res.setbodybytes(_(b'commands require POST requests'))
- return
-
- # At some point we'll want to use our own API instead of recycling the
- # behavior of version 1 of the wire protocol...
- # TODO return reasonable responses - not responses that overload the
- # HTTP status line message for error reporting.
- try:
- checkperm(rctx, req, b'pull' if permission == b'ro' else b'push')
- except hgwebcommon.ErrorResponse as e:
- res.status = hgwebcommon.statusmessage(
- e.code, stringutil.forcebytestr(e)
- )
- for k, v in e.headers:
- res.headers[k] = v
- res.setbodybytes(b'permission denied')
- return
-
- # We have a special endpoint to reflect the request back at the client.
- if command == b'debugreflect':
- _processhttpv2reflectrequest(rctx.repo.ui, rctx.repo, req, res)
- return
-
- # Extra commands that we handle that aren't really wire protocol
- # commands. Think extra hard before making this hackery available to
- # extension.
- extracommands = {b'multirequest'}
-
- if command not in COMMANDS and command not in extracommands:
- res.status = b'404 Not Found'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_(b'unknown wire protocol command: %s\n') % command)
- return
-
- repo = rctx.repo
- ui = repo.ui
-
- proto = httpv2protocolhandler(req, ui)
-
- if (
- not COMMANDS.commandavailable(command, proto)
- and command not in extracommands
- ):
- res.status = b'404 Not Found'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_(b'invalid wire protocol command: %s') % command)
- return
-
- # TODO consider cases where proxies may add additional Accept headers.
- if req.headers.get(b'Accept') != FRAMINGTYPE:
- res.status = b'406 Not Acceptable'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(
- _(b'client MUST specify Accept header with value: %s\n')
- % FRAMINGTYPE
- )
- return
-
- if req.headers.get(b'Content-Type') != FRAMINGTYPE:
- res.status = b'415 Unsupported Media Type'
- # TODO we should send a response with appropriate media type,
- # since client does Accept it.
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(
- _(b'client MUST send Content-Type header with value: %s\n')
- % FRAMINGTYPE
- )
- return
-
- _processhttpv2request(ui, repo, req, res, permission, command, proto)
-
-
-def _processhttpv2reflectrequest(ui, repo, req, res):
- """Reads unified frame protocol request and dumps out state to client.
-
- This special endpoint can be used to help debug the wire protocol.
-
- Instead of routing the request through the normal dispatch mechanism,
- we instead read all frames, decode them, and feed them into our state
- tracker. We then dump the log of all that activity back out to the
- client.
- """
- # Reflection APIs have a history of being abused, accidentally disclosing
- # sensitive data, etc. So we have a config knob.
- if not ui.configbool(b'experimental', b'web.api.debugreflect'):
- res.status = b'404 Not Found'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_(b'debugreflect service not available'))
- return
-
- # We assume we have a unified framing protocol request body.
-
- reactor = wireprotoframing.serverreactor(ui)
- states = []
-
- while True:
- frame = wireprotoframing.readframe(req.bodyfh)
-
- if not frame:
- states.append(b'received: <no frame>')
- break
-
- states.append(
- b'received: %d %d %d %s'
- % (frame.typeid, frame.flags, frame.requestid, frame.payload)
- )
-
- action, meta = reactor.onframerecv(frame)
- states.append(templatefilters.json((action, meta)))
-
- action, meta = reactor.oninputeof()
- meta[b'action'] = action
- states.append(templatefilters.json(meta))
-
- res.status = b'200 OK'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(b'\n'.join(states))
-
-
-def _processhttpv2request(ui, repo, req, res, authedperm, reqcommand, proto):
- """Post-validation handler for HTTPv2 requests.
-
- Called when the HTTP request contains unified frame-based protocol
- frames for evaluation.
- """
- # TODO Some HTTP clients are full duplex and can receive data before
- # the entire request is transmitted. Figure out a way to indicate support
- # for that so we can opt into full duplex mode.
- reactor = wireprotoframing.serverreactor(ui, deferoutput=True)
- seencommand = False
-
- outstream = None
-
- while True:
- frame = wireprotoframing.readframe(req.bodyfh)
- if not frame:
- break
-
- action, meta = reactor.onframerecv(frame)
-
- if action == b'wantframe':
- # Need more data before we can do anything.
- continue
- elif action == b'runcommand':
- # Defer creating output stream because we need to wait for
- # protocol settings frames so proper encoding can be applied.
- if not outstream:
- outstream = reactor.makeoutputstream()
-
- sentoutput = _httpv2runcommand(
- ui,
- repo,
- req,
- res,
- authedperm,
- reqcommand,
- reactor,
- outstream,
- meta,
- issubsequent=seencommand,
- )
-
- if sentoutput:
- return
-
- seencommand = True
-
- elif action == b'error':
- # TODO define proper error mechanism.
- res.status = b'200 OK'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(meta[b'message'] + b'\n')
- return
- else:
- raise error.ProgrammingError(
- b'unhandled action from frame processor: %s' % action
- )
-
- action, meta = reactor.oninputeof()
- if action == b'sendframes':
- # We assume we haven't started sending the response yet. If we're
- # wrong, the response type will raise an exception.
- res.status = b'200 OK'
- res.headers[b'Content-Type'] = FRAMINGTYPE
- res.setbodygen(meta[b'framegen'])
- elif action == b'noop':
- pass
- else:
- raise error.ProgrammingError(
- b'unhandled action from frame processor: %s' % action
- )
-
-
-def _httpv2runcommand(
- ui,
- repo,
- req,
- res,
- authedperm,
- reqcommand,
- reactor,
- outstream,
- command,
- issubsequent,
-):
- """Dispatch a wire protocol command made from HTTPv2 requests.
-
- The authenticated permission (``authedperm``) along with the original
- command from the URL (``reqcommand``) are passed in.
- """
- # We already validated that the session has permissions to perform the
- # actions in ``authedperm``. In the unified frame protocol, the canonical
- # command to run is expressed in a frame. However, the URL also requested
- # to run a specific command. We need to be careful that the command we
- # run doesn't have permissions requirements greater than what was granted
- # by ``authedperm``.
- #
- # Our rule for this is we only allow one command per HTTP request and
- # that command must match the command in the URL. However, we make
- # an exception for the ``multirequest`` URL. This URL is allowed to
- # execute multiple commands. We double check permissions of each command
- # as it is invoked to ensure there is no privilege escalation.
- # TODO consider allowing multiple commands to regular command URLs
- # iff each command is the same.
-
- proto = httpv2protocolhandler(req, ui, args=command[b'args'])
-
- if reqcommand == b'multirequest':
- if not COMMANDS.commandavailable(command[b'command'], proto):
- # TODO proper error mechanism
- res.status = b'200 OK'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(
- _(b'wire protocol command not available: %s')
- % command[b'command']
- )
- return True
-
- # TODO don't use assert here, since it may be elided by -O.
- assert authedperm in (b'ro', b'rw')
- wirecommand = COMMANDS[command[b'command']]
- assert wirecommand.permission in (b'push', b'pull')
-
- if authedperm == b'ro' and wirecommand.permission != b'pull':
- # TODO proper error mechanism
- res.status = b'403 Forbidden'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(
- _(b'insufficient permissions to execute command: %s')
- % command[b'command']
- )
- return True
-
- # TODO should we also call checkperm() here? Maybe not if we're going
- # to overhaul that API. The granted scope from the URL check should
- # be good enough.
-
- else:
- # Don't allow multiple commands outside of ``multirequest`` URL.
- if issubsequent:
- # TODO proper error mechanism
- res.status = b'200 OK'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(
- _(b'multiple commands cannot be issued to this URL')
- )
- return True
-
- if reqcommand != command[b'command']:
- # TODO define proper error mechanism
- res.status = b'200 OK'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_(b'command in frame must match command in URL'))
- return True
-
- res.status = b'200 OK'
- res.headers[b'Content-Type'] = FRAMINGTYPE
-
- try:
- objs = dispatch(repo, proto, command[b'command'], command[b'redirect'])
-
- action, meta = reactor.oncommandresponsereadyobjects(
- outstream, command[b'requestid'], objs
- )
-
- except error.WireprotoCommandError as e:
- action, meta = reactor.oncommanderror(
- outstream, command[b'requestid'], e.message, e.messageargs
- )
-
- except Exception as e:
- action, meta = reactor.onservererror(
- outstream,
- command[b'requestid'],
- _(b'exception when invoking command: %s')
- % stringutil.forcebytestr(e),
- )
-
- if action == b'sendframes':
- res.setbodygen(meta[b'framegen'])
- return True
- elif action == b'noop':
- return False
- else:
- raise error.ProgrammingError(
- b'unhandled event from reactor: %s' % action
- )
-
-
-def getdispatchrepo(repo, proto, command):
- viewconfig = repo.ui.config(b'server', b'view')
- return repo.filtered(viewconfig)
-
-
-def dispatch(repo, proto, command, redirect):
- """Run a wire protocol command.
-
- Returns an iterable of objects that will be sent to the client.
- """
- repo = getdispatchrepo(repo, proto, command)
-
- entry = COMMANDS[command]
- func = entry.func
- spec = entry.args
-
- args = proto.getargs(spec)
-
- # There is some duplicate boilerplate code here for calling the command and
- # emitting objects. It is either that or a lot of indented code that looks
- # like a pyramid (since there are a lot of code paths that result in not
- # using the cacher).
- callcommand = lambda: func(repo, proto, **pycompat.strkwargs(args))
-
- # Request is not cacheable. Don't bother instantiating a cacher.
- if not entry.cachekeyfn:
- for o in callcommand():
- yield o
- return
-
- if redirect:
- redirecttargets = redirect[b'targets']
- redirecthashes = redirect[b'hashes']
- else:
- redirecttargets = []
- redirecthashes = []
-
- cacher = makeresponsecacher(
- repo,
- proto,
- command,
- args,
- cborutil.streamencode,
- redirecttargets=redirecttargets,
- redirecthashes=redirecthashes,
- )
-
- # But we have no cacher. Do default handling.
- if not cacher:
- for o in callcommand():
- yield o
- return
-
- with cacher:
- cachekey = entry.cachekeyfn(
- repo, proto, cacher, **pycompat.strkwargs(args)
- )
-
- # No cache key or the cacher doesn't like it. Do default handling.
- if cachekey is None or not cacher.setcachekey(cachekey):
- for o in callcommand():
- yield o
- return
-
- # Serve it from the cache, if possible.
- cached = cacher.lookup()
-
- if cached:
- for o in cached[b'objs']:
- yield o
- return
-
- # Else call the command and feed its output into the cacher, allowing
- # the cacher to buffer/mutate objects as it desires.
- for o in callcommand():
- for o in cacher.onobject(o):
- yield o
-
- for o in cacher.onfinished():
- yield o
-
-
-@interfaceutil.implementer(wireprototypes.baseprotocolhandler)
-class httpv2protocolhandler(object):
- def __init__(self, req, ui, args=None):
- self._req = req
- self._ui = ui
- self._args = args
-
- @property
- def name(self):
- return HTTP_WIREPROTO_V2
-
- def getargs(self, args):
- # First look for args that were passed but aren't registered on this
- # command.
- extra = set(self._args) - set(args)
- if extra:
- raise error.WireprotoCommandError(
- b'unsupported argument to command: %s'
- % b', '.join(sorted(extra))
- )
-
- # And look for required arguments that are missing.
- missing = {a for a in args if args[a][b'required']} - set(self._args)
-
- if missing:
- raise error.WireprotoCommandError(
- b'missing required arguments: %s' % b', '.join(sorted(missing))
- )
-
- # Now derive the arguments to pass to the command, taking into
- # account the arguments specified by the client.
- data = {}
- for k, meta in sorted(args.items()):
- # This argument wasn't passed by the client.
- if k not in self._args:
- data[k] = meta[b'default']()
- continue
-
- v = self._args[k]
-
- # Sets may be expressed as lists. Silently normalize.
- if meta[b'type'] == b'set' and isinstance(v, list):
- v = set(v)
-
- # TODO consider more/stronger type validation.
-
- data[k] = v
-
- return data
-
- def getprotocaps(self):
- # Protocol capabilities are currently not implemented for HTTP V2.
- return set()
-
- def getpayload(self):
- raise NotImplementedError
-
- @contextlib.contextmanager
- def mayberedirectstdio(self):
- raise NotImplementedError
-
- def client(self):
- raise NotImplementedError
-
- def addcapabilities(self, repo, caps):
- return caps
-
- def checkperm(self, perm):
- raise NotImplementedError
-
-
-def httpv2apidescriptor(req, repo):
- proto = httpv2protocolhandler(req, repo.ui)
-
- return _capabilitiesv2(repo, proto)
-
-
-def _capabilitiesv2(repo, proto):
- """Obtain the set of capabilities for version 2 transports.
-
- These capabilities are distinct from the capabilities for version 1
- transports.
- """
- caps = {
- b'commands': {},
- b'framingmediatypes': [FRAMINGTYPE],
- b'pathfilterprefixes': set(narrowspec.VALID_PREFIXES),
- }
-
- for command, entry in COMMANDS.items():
- args = {}
-
- for arg, meta in entry.args.items():
- args[arg] = {
- # TODO should this be a normalized type using CBOR's
- # terminology?
- b'type': meta[b'type'],
- b'required': meta[b'required'],
- }
-
- if not meta[b'required']:
- args[arg][b'default'] = meta[b'default']()
-
- if meta[b'validvalues']:
- args[arg][b'validvalues'] = meta[b'validvalues']
-
- # TODO this type of check should be defined in a per-command callback.
- if (
- command == b'rawstorefiledata'
- and not streamclone.allowservergeneration(repo)
- ):
- continue
-
- # pytype: disable=unsupported-operands
- caps[b'commands'][command] = {
- b'args': args,
- b'permissions': [entry.permission],
- }
- # pytype: enable=unsupported-operands
-
- if entry.extracapabilitiesfn:
- extracaps = entry.extracapabilitiesfn(repo, proto)
- caps[b'commands'][command].update(extracaps)
-
- caps[b'rawrepoformats'] = sorted(repo.requirements & repo.supportedformats)
-
- targets = getadvertisedredirecttargets(repo, proto)
- if targets:
- caps[b'redirect'] = {
- b'targets': [],
- b'hashes': [b'sha256', b'sha1'],
- }
-
- for target in targets:
- entry = {
- b'name': target[b'name'],
- b'protocol': target[b'protocol'],
- b'uris': target[b'uris'],
- }
-
- for key in (b'snirequired', b'tlsversions'):
- if key in target:
- entry[key] = target[key]
-
- # pytype: disable=attribute-error
- caps[b'redirect'][b'targets'].append(entry)
- # pytype: enable=attribute-error
-
- return proto.addcapabilities(repo, caps)
-
-
-def getadvertisedredirecttargets(repo, proto):
- """Obtain a list of content redirect targets.
-
- Returns a list containing potential redirect targets that will be
- advertised in capabilities data. Each dict MUST have the following
- keys:
-
- name
- The name of this redirect target. This is the identifier clients use
- to refer to a target. It is transferred as part of every command
- request.
-
- protocol
- Network protocol used by this target. Typically this is the string
- in front of the ``://`` in a URL. e.g. ``https``.
-
- uris
- List of representative URIs for this target. Clients can use the
- URIs to test parsing for compatibility or for ordering preference
- for which target to use.
-
- The following optional keys are recognized:
-
- snirequired
- Bool indicating if Server Name Indication (SNI) is required to
- connect to this target.
-
- tlsversions
- List of bytes indicating which TLS versions are supported by this
- target.
-
- By default, clients reflect the target order advertised by servers
- and servers will use the first client-advertised target when picking
- a redirect target. So targets should be advertised in the order the
- server prefers they be used.
- """
- return []
-
-
-def wireprotocommand(
- name,
- args=None,
- permission=b'push',
- cachekeyfn=None,
- extracapabilitiesfn=None,
-):
- """Decorator to declare a wire protocol command.
-
- ``name`` is the name of the wire protocol command being provided.
-
- ``args`` is a dict defining arguments accepted by the command. Keys are
- the argument name. Values are dicts with the following keys:
-
- ``type``
- The argument data type. Must be one of the following string
- literals: ``bytes``, ``int``, ``list``, ``dict``, ``set``,
- or ``bool``.
-
- ``default``
- A callable returning the default value for this argument. If not
- specified, ``None`` will be the default value.
-
- ``example``
- An example value for this argument.
-
- ``validvalues``
- Set of recognized values for this argument.
-
- ``permission`` defines the permission type needed to run this command.
- Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
- respectively. Default is to assume command requires ``push`` permissions
- because otherwise commands not declaring their permissions could modify
- a repository that is supposed to be read-only.
-
- ``cachekeyfn`` defines an optional callable that can derive the
- cache key for this request.
-
- ``extracapabilitiesfn`` defines an optional callable that defines extra
- command capabilities/parameters that are advertised next to the command
- in the capabilities data structure describing the server. The callable
- receives as arguments the repository and protocol objects. It returns
- a dict of extra fields to add to the command descriptor.
-
- Wire protocol commands are generators of objects to be serialized and
- sent to the client.
-
- If a command raises an uncaught exception, this will be translated into
- a command error.
-
- All commands can opt in to being cacheable by defining a function
- (``cachekeyfn``) that is called to derive a cache key. This function
- receives the same arguments as the command itself plus a ``cacher``
- argument containing the active cacher for the request and returns a bytes
- containing the key in a cache the response to this command may be cached
- under.
- """
- transports = {
- k for k, v in wireprototypes.TRANSPORTS.items() if v[b'version'] == 2
- }
-
- if permission not in (b'push', b'pull'):
- raise error.ProgrammingError(
- b'invalid wire protocol permission; '
- b'got %s; expected "push" or "pull"' % permission
- )
-
- if args is None:
- args = {}
-
- if not isinstance(args, dict):
- raise error.ProgrammingError(
- b'arguments for version 2 commands must be declared as dicts'
- )
-
- for arg, meta in args.items():
- if arg == b'*':
- raise error.ProgrammingError(
- b'* argument name not allowed on version 2 commands'
- )
-
- if not isinstance(meta, dict):
- raise error.ProgrammingError(
- b'arguments for version 2 commands '
- b'must declare metadata as a dict'
- )
-
- if b'type' not in meta:
- raise error.ProgrammingError(
- b'%s argument for command %s does not '
- b'declare type field' % (arg, name)
- )
-
- if meta[b'type'] not in (
- b'bytes',
- b'int',
- b'list',
- b'dict',
- b'set',
- b'bool',
- ):
- raise error.ProgrammingError(
- b'%s argument for command %s has '
- b'illegal type: %s' % (arg, name, meta[b'type'])
- )
-
- if b'example' not in meta:
- raise error.ProgrammingError(
- b'%s argument for command %s does not '
- b'declare example field' % (arg, name)
- )
-
- meta[b'required'] = b'default' not in meta
-
- meta.setdefault(b'default', lambda: None)
- meta.setdefault(b'validvalues', None)
-
- def register(func):
- if name in COMMANDS:
- raise error.ProgrammingError(
- b'%s command already registered for version 2' % name
- )
-
- COMMANDS[name] = wireprototypes.commandentry(
- func,
- args=args,
- transports=transports,
- permission=permission,
- cachekeyfn=cachekeyfn,
- extracapabilitiesfn=extracapabilitiesfn,
- )
-
- return func
-
- return register
-
-
-def makecommandcachekeyfn(command, localversion=None, allargs=False):
- """Construct a cache key derivation function with common features.
-
- By default, the cache key is a hash of:
-
- * The command name.
- * A global cache version number.
- * A local cache version number (passed via ``localversion``).
- * All the arguments passed to the command.
- * The media type used.
- * Wire protocol version string.
- * The repository path.
- """
- if not allargs:
- raise error.ProgrammingError(
- b'only allargs=True is currently supported'
- )
-
- if localversion is None:
- raise error.ProgrammingError(b'must set localversion argument value')
-
- def cachekeyfn(repo, proto, cacher, **args):
- spec = COMMANDS[command]
-
- # Commands that mutate the repo can not be cached.
- if spec.permission == b'push':
- return None
-
- # TODO config option to disable caching.
-
- # Our key derivation strategy is to construct a data structure
- # holding everything that could influence cacheability and to hash
- # the CBOR representation of that. Using CBOR seems like it might
- # be overkill. However, simpler hashing mechanisms are prone to
- # duplicate input issues. e.g. if you just concatenate two values,
- # "foo"+"bar" is identical to "fo"+"obar". Using CBOR provides
- # "padding" between values and prevents these problems.
-
- # Seed the hash with various data.
- state = {
- # To invalidate all cache keys.
- b'globalversion': GLOBAL_CACHE_VERSION,
- # More granular cache key invalidation.
- b'localversion': localversion,
- # Cache keys are segmented by command.
- b'command': command,
- # Throw in the media type and API version strings so changes
- # to exchange semantics invalid cache.
- b'mediatype': FRAMINGTYPE,
- b'version': HTTP_WIREPROTO_V2,
- # So same requests for different repos don't share cache keys.
- b'repo': repo.root,
- }
-
- # The arguments passed to us will have already been normalized.
- # Default values will be set, etc. This is important because it
- # means that it doesn't matter if clients send an explicit argument
- # or rely on the default value: it will all normalize to the same
- # set of arguments on the server and therefore the same cache key.
- #
- # Arguments by their very nature must support being encoded to CBOR.
- # And the CBOR encoder is deterministic. So we hash the arguments
- # by feeding the CBOR of their representation into the hasher.
- if allargs:
- state[b'args'] = pycompat.byteskwargs(args)
-
- cacher.adjustcachekeystate(state)
-
- hasher = hashutil.sha1()
- for chunk in cborutil.streamencode(state):
- hasher.update(chunk)
-
- return pycompat.sysbytes(hasher.hexdigest())
-
- return cachekeyfn
-
-
-def makeresponsecacher(
- repo, proto, command, args, objencoderfn, redirecttargets, redirecthashes
-):
- """Construct a cacher for a cacheable command.
-
- Returns an ``iwireprotocolcommandcacher`` instance.
-
- Extensions can monkeypatch this function to provide custom caching
- backends.
- """
- return None
-
-
-def resolvenodes(repo, revisions):
- """Resolve nodes from a revisions specifier data structure."""
- cl = repo.changelog
- clhasnode = cl.hasnode
-
- seen = set()
- nodes = []
-
- if not isinstance(revisions, list):
- raise error.WireprotoCommandError(
- b'revisions must be defined as an array'
- )
-
- for spec in revisions:
- if b'type' not in spec:
- raise error.WireprotoCommandError(
- b'type key not present in revision specifier'
- )
-
- typ = spec[b'type']
-
- if typ == b'changesetexplicit':
- if b'nodes' not in spec:
- raise error.WireprotoCommandError(
- b'nodes key not present in changesetexplicit revision '
- b'specifier'
- )
-
- for node in spec[b'nodes']:
- if node not in seen:
- nodes.append(node)
- seen.add(node)
-
- elif typ == b'changesetexplicitdepth':
- for key in (b'nodes', b'depth'):
- if key not in spec:
- raise error.WireprotoCommandError(
- b'%s key not present in changesetexplicitdepth revision '
- b'specifier',
- (key,),
- )
-
- for rev in repo.revs(
- b'ancestors(%ln, %s)', spec[b'nodes'], spec[b'depth'] - 1
- ):
- node = cl.node(rev)
-
- if node not in seen:
- nodes.append(node)
- seen.add(node)
-
- elif typ == b'changesetdagrange':
- for key in (b'roots', b'heads'):
- if key not in spec:
- raise error.WireprotoCommandError(
- b'%s key not present in changesetdagrange revision '
- b'specifier',
- (key,),
- )
-
- if not spec[b'heads']:
- raise error.WireprotoCommandError(
- b'heads key in changesetdagrange cannot be empty'
- )
-
- if spec[b'roots']:
- common = [n for n in spec[b'roots'] if clhasnode(n)]
- else:
- common = [repo.nullid]
-
- for n in discovery.outgoing(repo, common, spec[b'heads']).missing:
- if n not in seen:
- nodes.append(n)
- seen.add(n)
-
- else:
- raise error.WireprotoCommandError(
- b'unknown revision specifier type: %s', (typ,)
- )
-
- return nodes
-
-
-@wireprotocommand(b'branchmap', permission=b'pull')
-def branchmapv2(repo, proto):
- yield {
- encoding.fromlocal(k): v
- for k, v in pycompat.iteritems(repo.branchmap())
- }
-
-
-@wireprotocommand(b'capabilities', permission=b'pull')
-def capabilitiesv2(repo, proto):
- yield _capabilitiesv2(repo, proto)
-
-
-@wireprotocommand(
- b'changesetdata',
- args={
- b'revisions': {
- b'type': b'list',
- b'example': [
- {
- b'type': b'changesetexplicit',
- b'nodes': [b'abcdef...'],
- }
- ],
- },
- b'fields': {
- b'type': b'set',
- b'default': set,
- b'example': {b'parents', b'revision'},
- b'validvalues': {b'bookmarks', b'parents', b'phase', b'revision'},
- },
- },
- permission=b'pull',
-)
-def changesetdata(repo, proto, revisions, fields):
- # TODO look for unknown fields and abort when they can't be serviced.
- # This could probably be validated by dispatcher using validvalues.
-
- cl = repo.changelog
- outgoing = resolvenodes(repo, revisions)
- publishing = repo.publishing()
-
- if outgoing:
- repo.hook(b'preoutgoing', throw=True, source=b'serve')
-
- yield {
- b'totalitems': len(outgoing),
- }
-
- # The phases of nodes already transferred to the client may have changed
- # since the client last requested data. We send phase-only records
- # for these revisions, if requested.
- # TODO actually do this. We'll probably want to emit phase heads
- # in the ancestry set of the outgoing revisions. This will ensure
- # that phase updates within that set are seen.
- if b'phase' in fields:
- pass
-
- nodebookmarks = {}
- for mark, node in repo._bookmarks.items():
- nodebookmarks.setdefault(node, set()).add(mark)
-
- # It is already topologically sorted by revision number.
- for node in outgoing:
- d = {
- b'node': node,
- }
-
- if b'parents' in fields:
- d[b'parents'] = cl.parents(node)
-
- if b'phase' in fields:
- if publishing:
- d[b'phase'] = b'public'
- else:
- ctx = repo[node]
- d[b'phase'] = ctx.phasestr()
-
- if b'bookmarks' in fields and node in nodebookmarks:
- d[b'bookmarks'] = sorted(nodebookmarks[node])
- del nodebookmarks[node]
-
- followingmeta = []
- followingdata = []
-
- if b'revision' in fields:
- revisiondata = cl.revision(node)
- followingmeta.append((b'revision', len(revisiondata)))
- followingdata.append(revisiondata)
-
- # TODO make it possible for extensions to wrap a function or register
- # a handler to service custom fields.
-
- if followingmeta:
- d[b'fieldsfollowing'] = followingmeta
-
- yield d
-
- for extra in followingdata:
- yield extra
-
- # If requested, send bookmarks from nodes that didn't have revision
- # data sent so receiver is aware of any bookmark updates.
- if b'bookmarks' in fields:
- for node, marks in sorted(pycompat.iteritems(nodebookmarks)):
- yield {
- b'node': node,
- b'bookmarks': sorted(marks),
- }
-
-
-class FileAccessError(Exception):
- """Represents an error accessing a specific file."""
-
- def __init__(self, path, msg, args):
- self.path = path
- self.msg = msg
- self.args = args
-
-
-def getfilestore(repo, proto, path):
- """Obtain a file storage object for use with wire protocol.
-
- Exists as a standalone function so extensions can monkeypatch to add
- access control.
- """
- # This seems to work even if the file doesn't exist. So catch
- # "empty" files and return an error.
- fl = repo.file(path)
-
- if not len(fl):
- raise FileAccessError(path, b'unknown file: %s', (path,))
-
- return fl
-
-
-def emitfilerevisions(repo, path, revisions, linknodes, fields):
- for revision in revisions:
- d = {
- b'node': revision.node,
- }
-
- if b'parents' in fields:
- d[b'parents'] = [revision.p1node, revision.p2node]
-
- if b'linknode' in fields:
- d[b'linknode'] = linknodes[revision.node]
-
- followingmeta = []
- followingdata = []
-
- if b'revision' in fields:
- if revision.revision is not None:
- followingmeta.append((b'revision', len(revision.revision)))
- followingdata.append(revision.revision)
- else:
- d[b'deltabasenode'] = revision.basenode
- followingmeta.append((b'delta', len(revision.delta)))
- followingdata.append(revision.delta)
-
- if followingmeta:
- d[b'fieldsfollowing'] = followingmeta
-
- yield d
-
- for extra in followingdata:
- yield extra
-
-
-def makefilematcher(repo, pathfilter):
- """Construct a matcher from a path filter dict."""
-
- # Validate values.
- if pathfilter:
- for key in (b'include', b'exclude'):
- for pattern in pathfilter.get(key, []):
- if not pattern.startswith((b'path:', b'rootfilesin:')):
- raise error.WireprotoCommandError(
- b'%s pattern must begin with `path:` or `rootfilesin:`; '
- b'got %s',
- (key, pattern),
- )
-
- if pathfilter:
- matcher = matchmod.match(
- repo.root,
- b'',
- include=pathfilter.get(b'include', []),
- exclude=pathfilter.get(b'exclude', []),
- )
- else:
- matcher = matchmod.match(repo.root, b'')
-
- # Requested patterns could include files not in the local store. So
- # filter those out.
- return repo.narrowmatch(matcher)
-
-
-@wireprotocommand(
- b'filedata',
- args={
- b'haveparents': {
- b'type': b'bool',
- b'default': lambda: False,
- b'example': True,
- },
- b'nodes': {
- b'type': b'list',
- b'example': [b'0123456...'],
- },
- b'fields': {
- b'type': b'set',
- b'default': set,
- b'example': {b'parents', b'revision'},
- b'validvalues': {b'parents', b'revision', b'linknode'},
- },
- b'path': {
- b'type': b'bytes',
- b'example': b'foo.txt',
- },
- },
- permission=b'pull',
- # TODO censoring a file revision won't invalidate the cache.
- # Figure out a way to take censoring into account when deriving
- # the cache key.
- cachekeyfn=makecommandcachekeyfn(b'filedata', 1, allargs=True),
-)
-def filedata(repo, proto, haveparents, nodes, fields, path):
- # TODO this API allows access to file revisions that are attached to
- # secret changesets. filesdata does not have this problem. Maybe this
- # API should be deleted?
-
- try:
- # Extensions may wish to access the protocol handler.
- store = getfilestore(repo, proto, path)
- except FileAccessError as e:
- raise error.WireprotoCommandError(e.msg, e.args)
-
- clnode = repo.changelog.node
- linknodes = {}
-
- # Validate requested nodes.
- for node in nodes:
- try:
- store.rev(node)
- except error.LookupError:
- raise error.WireprotoCommandError(
- b'unknown file node: %s', (hex(node),)
- )
-
- # TODO by creating the filectx against a specific file revision
- # instead of changeset, linkrev() is always used. This is wrong for
- # cases where linkrev() may refer to a hidden changeset. But since this
- # API doesn't know anything about changesets, we're not sure how to
- # disambiguate the linknode. Perhaps we should delete this API?
- fctx = repo.filectx(path, fileid=node)
- linknodes[node] = clnode(fctx.introrev())
-
- revisions = store.emitrevisions(
- nodes,
- revisiondata=b'revision' in fields,
- assumehaveparentrevisions=haveparents,
- )
-
- yield {
- b'totalitems': len(nodes),
- }
-
- for o in emitfilerevisions(repo, path, revisions, linknodes, fields):
- yield o
-
-
-def filesdatacapabilities(repo, proto):
- batchsize = repo.ui.configint(
- b'experimental', b'server.filesdata.recommended-batch-size'
- )
- return {
- b'recommendedbatchsize': batchsize,
- }
-
-
-@wireprotocommand(
- b'filesdata',
- args={
- b'haveparents': {
- b'type': b'bool',
- b'default': lambda: False,
- b'example': True,
- },
- b'fields': {
- b'type': b'set',
- b'default': set,
- b'example': {b'parents', b'revision'},
- b'validvalues': {
- b'firstchangeset',
- b'linknode',
- b'parents',
- b'revision',
- },
- },
- b'pathfilter': {
- b'type': b'dict',
- b'default': lambda: None,
- b'example': {b'include': [b'path:tests']},
- },
- b'revisions': {
- b'type': b'list',
- b'example': [
- {
- b'type': b'changesetexplicit',
- b'nodes': [b'abcdef...'],
- }
- ],
- },
- },
- permission=b'pull',
- # TODO censoring a file revision won't invalidate the cache.
- # Figure out a way to take censoring into account when deriving
- # the cache key.
- cachekeyfn=makecommandcachekeyfn(b'filesdata', 1, allargs=True),
- extracapabilitiesfn=filesdatacapabilities,
-)
-def filesdata(repo, proto, haveparents, fields, pathfilter, revisions):
- # TODO This should operate on a repo that exposes obsolete changesets. There
- # is a race between a client making a push that obsoletes a changeset and
- # another client fetching files data for that changeset. If a client has a
- # changeset, it should probably be allowed to access files data for that
- # changeset.
-
- outgoing = resolvenodes(repo, revisions)
- filematcher = makefilematcher(repo, pathfilter)
-
- # path -> {fnode: linknode}
- fnodes = collections.defaultdict(dict)
-
- # We collect the set of relevant file revisions by iterating the changeset
- # revisions and either walking the set of files recorded in the changeset
- # or by walking the manifest at that revision. There is probably room for a
- # storage-level API to request this data, as it can be expensive to compute
- # and would benefit from caching or alternate storage from what revlogs
- # provide.
- for node in outgoing:
- ctx = repo[node]
- mctx = ctx.manifestctx()
- md = mctx.read()
-
- if haveparents:
- checkpaths = ctx.files()
- else:
- checkpaths = md.keys()
-
- for path in checkpaths:
- fnode = md[path]
-
- if path in fnodes and fnode in fnodes[path]:
- continue
-
- if not filematcher(path):
- continue
-
- fnodes[path].setdefault(fnode, node)
-
- yield {
- b'totalpaths': len(fnodes),
- b'totalitems': sum(len(v) for v in fnodes.values()),
- }
-
- for path, filenodes in sorted(fnodes.items()):
- try:
- store = getfilestore(repo, proto, path)
- except FileAccessError as e:
- raise error.WireprotoCommandError(e.msg, e.args)
-
- yield {
- b'path': path,
- b'totalitems': len(filenodes),
- }
-
- revisions = store.emitrevisions(
- filenodes.keys(),
- revisiondata=b'revision' in fields,
- assumehaveparentrevisions=haveparents,
- )
-
- for o in emitfilerevisions(repo, path, revisions, filenodes, fields):
- yield o
-
-
-@wireprotocommand(
- b'heads',
- args={
- b'publiconly': {
- b'type': b'bool',
- b'default': lambda: False,
- b'example': False,
- },
- },
- permission=b'pull',
-)
-def headsv2(repo, proto, publiconly):
- if publiconly:
- repo = repo.filtered(b'immutable')
-
- yield repo.heads()
-
-
-@wireprotocommand(
- b'known',
- args={
- b'nodes': {
- b'type': b'list',
- b'default': list,
- b'example': [b'deadbeef'],
- },
- },
- permission=b'pull',
-)
-def knownv2(repo, proto, nodes):
- result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
- yield result
-
-
-@wireprotocommand(
- b'listkeys',
- args={
- b'namespace': {
- b'type': b'bytes',
- b'example': b'ns',
- },
- },
- permission=b'pull',
-)
-def listkeysv2(repo, proto, namespace):
- keys = repo.listkeys(encoding.tolocal(namespace))
- keys = {
- encoding.fromlocal(k): encoding.fromlocal(v)
- for k, v in pycompat.iteritems(keys)
- }
-
- yield keys
-
-
-@wireprotocommand(
- b'lookup',
- args={
- b'key': {
- b'type': b'bytes',
- b'example': b'foo',
- },
- },
- permission=b'pull',
-)
-def lookupv2(repo, proto, key):
- key = encoding.tolocal(key)
-
- # TODO handle exception.
- node = repo.lookup(key)
-
- yield node
-
-
-def manifestdatacapabilities(repo, proto):
- batchsize = repo.ui.configint(
- b'experimental', b'server.manifestdata.recommended-batch-size'
- )
-
- return {
- b'recommendedbatchsize': batchsize,
- }
-
-
-@wireprotocommand(
- b'manifestdata',
- args={
- b'nodes': {
- b'type': b'list',
- b'example': [b'0123456...'],
- },
- b'haveparents': {
- b'type': b'bool',
- b'default': lambda: False,
- b'example': True,
- },
- b'fields': {
- b'type': b'set',
- b'default': set,
- b'example': {b'parents', b'revision'},
- b'validvalues': {b'parents', b'revision'},
- },
- b'tree': {
- b'type': b'bytes',
- b'example': b'',
- },
- },
- permission=b'pull',
- cachekeyfn=makecommandcachekeyfn(b'manifestdata', 1, allargs=True),
- extracapabilitiesfn=manifestdatacapabilities,
-)
-def manifestdata(repo, proto, haveparents, nodes, fields, tree):
- store = repo.manifestlog.getstorage(tree)
-
- # Validate the node is known and abort on unknown revisions.
- for node in nodes:
- try:
- store.rev(node)
- except error.LookupError:
- raise error.WireprotoCommandError(b'unknown node: %s', (node,))
-
- revisions = store.emitrevisions(
- nodes,
- revisiondata=b'revision' in fields,
- assumehaveparentrevisions=haveparents,
- )
-
- yield {
- b'totalitems': len(nodes),
- }
-
- for revision in revisions:
- d = {
- b'node': revision.node,
- }
-
- if b'parents' in fields:
- d[b'parents'] = [revision.p1node, revision.p2node]
-
- followingmeta = []
- followingdata = []
-
- if b'revision' in fields:
- if revision.revision is not None:
- followingmeta.append((b'revision', len(revision.revision)))
- followingdata.append(revision.revision)
- else:
- d[b'deltabasenode'] = revision.basenode
- followingmeta.append((b'delta', len(revision.delta)))
- followingdata.append(revision.delta)
-
- if followingmeta:
- d[b'fieldsfollowing'] = followingmeta
-
- yield d
-
- for extra in followingdata:
- yield extra
-
-
-@wireprotocommand(
- b'pushkey',
- args={
- b'namespace': {
- b'type': b'bytes',
- b'example': b'ns',
- },
- b'key': {
- b'type': b'bytes',
- b'example': b'key',
- },
- b'old': {
- b'type': b'bytes',
- b'example': b'old',
- },
- b'new': {
- b'type': b'bytes',
- b'example': b'new',
- },
- },
- permission=b'push',
-)
-def pushkeyv2(repo, proto, namespace, key, old, new):
- # TODO handle ui output redirection
- yield repo.pushkey(
- encoding.tolocal(namespace),
- encoding.tolocal(key),
- encoding.tolocal(old),
- encoding.tolocal(new),
- )
-
-
-@wireprotocommand(
- b'rawstorefiledata',
- args={
- b'files': {
- b'type': b'list',
- b'example': [b'changelog', b'manifestlog'],
- },
- b'pathfilter': {
- b'type': b'list',
- b'default': lambda: None,
- b'example': {b'include': [b'path:tests']},
- },
- },
- permission=b'pull',
-)
-def rawstorefiledata(repo, proto, files, pathfilter):
- if not streamclone.allowservergeneration(repo):
- raise error.WireprotoCommandError(b'stream clone is disabled')
-
- # TODO support dynamically advertising what store files "sets" are
- # available. For now, we support changelog, manifestlog, and files.
- files = set(files)
- allowedfiles = {b'changelog', b'manifestlog'}
-
- unsupported = files - allowedfiles
- if unsupported:
- raise error.WireprotoCommandError(
- b'unknown file type: %s', (b', '.join(sorted(unsupported)),)
- )
-
- with repo.lock():
- topfiles = list(repo.store.topfiles())
-
- sendfiles = []
- totalsize = 0
-
- # TODO this is a bunch of storage layer interface abstractions because
- # it assumes revlogs.
- for rl_type, name, size in topfiles:
- # XXX use the `rl_type` for that
- if b'changelog' in files and name.startswith(b'00changelog'):
- pass
- elif b'manifestlog' in files and name.startswith(b'00manifest'):
- pass
- else:
- continue
-
- sendfiles.append((b'store', name, size))
- totalsize += size
-
- yield {
- b'filecount': len(sendfiles),
- b'totalsize': totalsize,
- }
-
- for location, name, size in sendfiles:
- yield {
- b'location': location,
- b'path': name,
- b'size': size,
- }
-
- # We have to use a closure for this to ensure the context manager is
- # closed only after sending the final chunk.
- def getfiledata():
- with repo.svfs(name, b'rb', auditpath=False) as fh:
- for chunk in util.filechunkiter(fh, limit=size):
- yield chunk
-
- yield wireprototypes.indefinitebytestringresponse(getfiledata())
--- a/tests/test-bookmarks-pushpull.t Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-bookmarks-pushpull.t Tue Dec 07 16:44:22 2021 +0100
@@ -715,14 +715,15 @@
$ cat <<EOF > ../lookuphook.py
> """small extensions adding a hook after wireprotocol lookup to test race"""
> import functools
- > from mercurial import wireprotov1server, wireprotov2server
+ > from mercurial import wireprotov1server
>
> def wrappedlookup(orig, repo, *args, **kwargs):
> ret = orig(repo, *args, **kwargs)
> repo.hook(b'lookup')
> return ret
- > for table in [wireprotov1server.commands, wireprotov2server.COMMANDS]:
- > table[b'lookup'].func = functools.partial(wrappedlookup, table[b'lookup'].func)
+ >
+ > table = wireprotov1server.commands
+ > table[b'lookup'].func = functools.partial(wrappedlookup, table[b'lookup'].func)
> EOF
$ cat <<EOF > ../pull-race/.hg/hgrc
> [extensions]
--- a/tests/test-bundle2-exchange.t Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-bundle2-exchange.t Tue Dec 07 16:44:22 2021 +0100
@@ -1,13 +1,3 @@
-#testcases sshv1 sshv2
-
-#if sshv2
- $ cat >> $HGRCPATH << EOF
- > [experimental]
- > sshpeer.advertise-v2 = true
- > sshserver.support-v2 = true
- > EOF
-#endif
-
Test exchange of common information using bundle2
--- a/tests/test-bundle2-pushback.t Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-bundle2-pushback.t Tue Dec 07 16:44:22 2021 +0100
@@ -1,13 +1,3 @@
-#testcases sshv1 sshv2
-
-#if sshv2
- $ cat >> $HGRCPATH << EOF
- > [experimental]
- > sshpeer.advertise-v2 = true
- > sshserver.support-v2 = true
- > EOF
-#endif
-
$ cat > bundle2.py << EOF
> """A small extension to test bundle2 pushback parts.
> Current bundle2 implementation doesn't provide a way to generate those
--- a/tests/test-bundle2-remote-changegroup.t Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-bundle2-remote-changegroup.t Tue Dec 07 16:44:22 2021 +0100
@@ -1,13 +1,3 @@
-#testcases sshv1 sshv2
-
-#if sshv2
- $ cat >> $HGRCPATH << EOF
- > [experimental]
- > sshpeer.advertise-v2 = true
- > sshserver.support-v2 = true
- > EOF
-#endif
-
Create an extension to test bundle2 remote-changegroup parts
$ cat > bundle2.py << EOF
--- a/tests/test-check-interfaces.py Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-check-interfaces.py Tue Dec 07 16:44:22 2021 +0100
@@ -39,7 +39,6 @@
wireprotoserver,
wireprototypes,
wireprotov1peer,
- wireprotov2server,
)
testdir = os.path.dirname(__file__)
@@ -129,9 +128,6 @@
ziverify.verifyClass(repository.ipeerbase, httppeer.httppeer)
checkzobject(httppeer.httppeer(None, None, None, dummyopener(), None, None))
- ziverify.verifyClass(repository.ipeerv2, httppeer.httpv2peer)
- checkzobject(httppeer.httpv2peer(None, b'', b'', None, None, None))
-
ziverify.verifyClass(repository.ipeerbase, localrepo.localpeer)
checkzobject(localrepo.localpeer(dummyrepo()))
@@ -158,19 +154,6 @@
)
)
- ziverify.verifyClass(repository.ipeerbase, sshpeer.sshv2peer)
- checkzobject(
- sshpeer.sshv2peer(
- ui,
- b'ssh://localhost/foo',
- b'',
- dummypipe(),
- dummypipe(),
- None,
- None,
- )
- )
-
ziverify.verifyClass(repository.ipeerbase, bundlerepo.bundlepeer)
checkzobject(bundlerepo.bundlepeer(dummyrepo()))
@@ -193,26 +176,15 @@
wireprototypes.baseprotocolhandler, wireprotoserver.sshv1protocolhandler
)
ziverify.verifyClass(
- wireprototypes.baseprotocolhandler, wireprotoserver.sshv2protocolhandler
- )
- ziverify.verifyClass(
wireprototypes.baseprotocolhandler,
wireprotoserver.httpv1protocolhandler,
)
- ziverify.verifyClass(
- wireprototypes.baseprotocolhandler,
- wireprotov2server.httpv2protocolhandler,
- )
sshv1 = wireprotoserver.sshv1protocolhandler(None, None, None)
checkzobject(sshv1)
- sshv2 = wireprotoserver.sshv2protocolhandler(None, None, None)
- checkzobject(sshv2)
httpv1 = wireprotoserver.httpv1protocolhandler(None, None, None)
checkzobject(httpv1)
- httpv2 = wireprotov2server.httpv2protocolhandler(None, None)
- checkzobject(httpv2)
ziverify.verifyClass(repository.ifilestorage, filelog.filelog)
ziverify.verifyClass(repository.imanifestdict, manifest.manifestdict)
--- a/tests/test-clone.t Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-clone.t Tue Dec 07 16:44:22 2021 +0100
@@ -1,13 +1,3 @@
-#testcases sshv1 sshv2
-
-#if sshv2
- $ cat >> $HGRCPATH << EOF
- > [experimental]
- > sshpeer.advertise-v2 = true
- > sshserver.support-v2 = true
- > EOF
-#endif
-
Prepare repo a:
$ hg init a
@@ -1206,14 +1196,12 @@
#if windows
$ hg clone "ssh://%26touch%20owned%20/" --debug
running sh -c "read l; read l; read l" "&touch owned " "hg -R . serve --stdio"
- sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
sending hello command
sending between command
abort: no suitable response from remote hg
[255]
$ hg clone "ssh://example.com:%26touch%20owned%20/" --debug
running sh -c "read l; read l; read l" -p "&touch owned " example.com "hg -R . serve --stdio"
- sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
sending hello command
sending between command
abort: no suitable response from remote hg
@@ -1221,14 +1209,12 @@
#else
$ hg clone "ssh://%3btouch%20owned%20/" --debug
running sh -c "read l; read l; read l" ';touch owned ' 'hg -R . serve --stdio'
- sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
sending hello command
sending between command
abort: no suitable response from remote hg
[255]
$ hg clone "ssh://example.com:%3btouch%20owned%20/" --debug
running sh -c "read l; read l; read l" -p ';touch owned ' example.com 'hg -R . serve --stdio'
- sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
sending hello command
sending between command
abort: no suitable response from remote hg
@@ -1237,7 +1223,6 @@
$ hg clone "ssh://v-alid.example.com/" --debug
running sh -c "read l; read l; read l" v-alid\.example\.com ['"]hg -R \. serve --stdio['"] (re)
- sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
sending hello command
sending between command
abort: no suitable response from remote hg
--- a/tests/test-http-api-httpv2.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,743 +0,0 @@
-#require no-chg
-
- $ . $TESTDIR/wireprotohelpers.sh
- $ enabledummycommands
-
- $ hg init server
- $ cat > server/.hg/hgrc << EOF
- > [experimental]
- > web.apiserver = true
- > EOF
- $ hg -R server serve -p $HGPORT -d --pid-file hg.pid
- $ cat hg.pid > $DAEMON_PIDS
-
-HTTP v2 protocol not enabled by default
-
- $ sendhttpraw << EOF
- > httprequest GET api/$HTTPV2
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /api/exp-http-v2-0003 HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 404 Not Found\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 33\r\n
- s> \r\n
- s> API exp-http-v2-0003 not enabled\n
-
-Restart server with support for HTTP v2 API
-
- $ killdaemons.py
- $ enablehttpv2 server
- $ hg -R server serve -p $HGPORT -d --pid-file hg.pid
- $ cat hg.pid > $DAEMON_PIDS
-
-Request to unknown command yields 404
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/ro/badcommand
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/badcommand HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 404 Not Found\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 42\r\n
- s> \r\n
- s> unknown wire protocol command: badcommand\n
-
-GET to read-only command yields a 405
-
- $ sendhttpraw << EOF
- > httprequest GET api/$HTTPV2/ro/customreadonly
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /api/exp-http-v2-0003/ro/customreadonly HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 405 Method Not Allowed\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Allow: POST\r\n
- s> Content-Length: 30\r\n
- s> \r\n
- s> commands require POST requests
-
-Missing Accept header results in 406
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/ro/customreadonly
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/customreadonly HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 406 Not Acceptable\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 85\r\n
- s> \r\n
- s> client MUST specify Accept header with value: application/mercurial-exp-framing-0006\n
-
-Bad Accept header results in 406
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/ro/customreadonly
- > accept: invalid
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/customreadonly HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: invalid\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 406 Not Acceptable\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 85\r\n
- s> \r\n
- s> client MUST specify Accept header with value: application/mercurial-exp-framing-0006\n
-
-Bad Content-Type header results in 415
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/ro/customreadonly
- > accept: $MEDIATYPE
- > user-agent: test
- > content-type: badmedia
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/customreadonly HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: badmedia\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 415 Unsupported Media Type\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 88\r\n
- s> \r\n
- s> client MUST send Content-Type header with value: application/mercurial-exp-framing-0006\n
-
-Request to read-only command works out of the box
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/ro/customreadonly
- > accept: $MEDIATYPE
- > content-type: $MEDIATYPE
- > user-agent: test
- > frame 1 1 stream-begin command-request new cbor:{b'name': b'customreadonly'}
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/customreadonly HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> *\r\n (glob)
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> user-agent: test\r\n
- s> content-length: 29\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> \x15\x00\x00\x01\x00\x01\x01\x11\xa1DnameNcustomreadonly
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x01\x00\x02\x01\x92Hidentity
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x01\x00\x02\x041\xa1FstatusBok
- s> \r\n
- s> 27\r\n
- s> \x1f\x00\x00\x01\x00\x02\x041X\x1dcustomreadonly bytes response
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x01\x00\x02\x002
- s> \r\n
- s> 0\r\n
- s> \r\n
-
- $ sendhttpv2peerverbose << EOF
- > command customreadonly
- > EOF
- creating http peer for wire protocol version 2
- sending customreadonly command
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/customreadonly HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> content-length: 65\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> \x1c\x00\x00\x01\x00\x01\x01\x82\xa1Pcontentencodings\x81Hidentity\x15\x00\x00\x01\x00\x01\x00\x11\xa1DnameNcustomreadonly
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x01\x00\x02\x01\x92
- s> Hidentity
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x01\x00\x02\x041
- s> \xa1FstatusBok
- s> \r\n
- s> 27\r\n
- s> \x1f\x00\x00\x01\x00\x02\x041
- s> X\x1dcustomreadonly bytes response
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x01\x00\x02\x002
- s> \r\n
- s> 0\r\n
- s> \r\n
- response: gen[
- b'customreadonly bytes response'
- ]
- (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
-
-Request to read-write command fails because server is read-only by default
-
-GET to read-write request yields 405
-
- $ sendhttpraw << EOF
- > httprequest GET api/$HTTPV2/rw/customreadonly
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /api/exp-http-v2-0003/rw/customreadonly HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 405 Method Not Allowed\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Allow: POST\r\n
- s> Content-Length: 30\r\n
- s> \r\n
- s> commands require POST requests
-
-Even for unknown commands
-
- $ sendhttpraw << EOF
- > httprequest GET api/$HTTPV2/rw/badcommand
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /api/exp-http-v2-0003/rw/badcommand HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 405 Method Not Allowed\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Allow: POST\r\n
- s> Content-Length: 30\r\n
- s> \r\n
- s> commands require POST requests
-
-SSL required by default
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/rw/customreadonly
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/rw/customreadonly HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 403 ssl required\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Length: 17\r\n
- s> \r\n
- s> permission denied
-
-Restart server to allow non-ssl read-write operations
-
- $ killdaemons.py
- $ cat > server/.hg/hgrc << EOF
- > [experimental]
- > web.apiserver = true
- > web.api.http-v2 = true
- > [web]
- > push_ssl = false
- > allow-push = *
- > EOF
-
- $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-Authorized request for valid read-write command works
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/rw/customreadonly
- > user-agent: test
- > accept: $MEDIATYPE
- > content-type: $MEDIATYPE
- > frame 1 1 stream-begin command-request new cbor:{b'name': b'customreadonly'}
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/rw/customreadonly HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> user-agent: test\r\n
- s> content-length: 29\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> \x15\x00\x00\x01\x00\x01\x01\x11\xa1DnameNcustomreadonly
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x01\x00\x02\x01\x92Hidentity
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x01\x00\x02\x041\xa1FstatusBok
- s> \r\n
- s> 27\r\n
- s> \x1f\x00\x00\x01\x00\x02\x041X\x1dcustomreadonly bytes response
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x01\x00\x02\x002
- s> \r\n
- s> 0\r\n
- s> \r\n
-
-Authorized request for unknown command is rejected
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/rw/badcommand
- > user-agent: test
- > accept: $MEDIATYPE
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/rw/badcommand HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 404 Not Found\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 42\r\n
- s> \r\n
- s> unknown wire protocol command: badcommand\n
-
-debugreflect isn't enabled by default
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/ro/debugreflect
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/debugreflect HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 404 Not Found\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 34\r\n
- s> \r\n
- s> debugreflect service not available
-
-Restart server to get debugreflect endpoint
-
- $ killdaemons.py
- $ cat > server/.hg/hgrc << EOF
- > [experimental]
- > web.apiserver = true
- > web.api.debugreflect = true
- > web.api.http-v2 = true
- > [web]
- > push_ssl = false
- > allow-push = *
- > EOF
-
- $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-Command frames can be reflected via debugreflect
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/ro/debugreflect
- > accept: $MEDIATYPE
- > content-type: $MEDIATYPE
- > user-agent: test
- > frame 1 1 stream-begin command-request new cbor:{b'name': b'command1', b'args': {b'foo': b'val1', b'bar1': b'val'}}
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/debugreflect HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> user-agent: test\r\n
- s> content-length: 47\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> \'\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Dbar1CvalCfooDval1DnameHcommand1
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 223\r\n
- s> \r\n
- s> received: 1 1 1 \xa2Dargs\xa2Dbar1CvalCfooDval1DnameHcommand1\n
- s> ["runcommand", {"args": {"bar1": "val", "foo": "val1"}, "command": "command1", "data": null, "redirect": null, "requestid": 1}]\n
- s> received: <no frame>\n
- s> {"action": "noop"}
-
-Multiple requests to regular command URL are not allowed
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/ro/customreadonly
- > accept: $MEDIATYPE
- > content-type: $MEDIATYPE
- > user-agent: test
- > frame 1 1 stream-begin command-request new cbor:{b'name': b'customreadonly'}
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/customreadonly HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> user-agent: test\r\n
- s> content-length: 29\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> \x15\x00\x00\x01\x00\x01\x01\x11\xa1DnameNcustomreadonly
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x01\x00\x02\x01\x92Hidentity
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x01\x00\x02\x041\xa1FstatusBok
- s> \r\n
- s> 27\r\n
- s> \x1f\x00\x00\x01\x00\x02\x041X\x1dcustomreadonly bytes response
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x01\x00\x02\x002
- s> \r\n
- s> 0\r\n
- s> \r\n
-
-Multiple requests to "multirequest" URL are allowed
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/ro/multirequest
- > accept: $MEDIATYPE
- > content-type: $MEDIATYPE
- > user-agent: test
- > frame 1 1 stream-begin command-request new cbor:{b'name': b'customreadonly'}
- > frame 3 1 0 command-request new cbor:{b'name': b'customreadonly'}
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/multirequest HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> *\r\n (glob)
- s> *\r\n (glob)
- s> user-agent: test\r\n
- s> content-length: 58\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> \x15\x00\x00\x01\x00\x01\x01\x11\xa1DnameNcustomreadonly\x15\x00\x00\x03\x00\x01\x00\x11\xa1DnameNcustomreadonly
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x01\x00\x02\x01\x92Hidentity
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x01\x00\x02\x041\xa1FstatusBok
- s> \r\n
- s> 27\r\n
- s> \x1f\x00\x00\x01\x00\x02\x041X\x1dcustomreadonly bytes response
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x01\x00\x02\x002
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x03\x00\x02\x041\xa1FstatusBok
- s> \r\n
- s> 27\r\n
- s> \x1f\x00\x00\x03\x00\x02\x041X\x1dcustomreadonly bytes response
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x03\x00\x02\x002
- s> \r\n
- s> 0\r\n
- s> \r\n
-
-Interleaved requests to "multirequest" are processed
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/ro/multirequest
- > accept: $MEDIATYPE
- > content-type: $MEDIATYPE
- > user-agent: test
- > frame 1 1 stream-begin command-request new|more \xa2Dargs\xa1Inamespace
- > frame 3 1 0 command-request new|more \xa2Dargs\xa1Inamespace
- > frame 3 1 0 command-request continuation JnamespacesDnameHlistkeys
- > frame 1 1 0 command-request continuation IbookmarksDnameHlistkeys
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/multirequest HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> user-agent: test\r\n
- s> content-length: 115\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> \x11\x00\x00\x01\x00\x01\x01\x15\xa2Dargs\xa1Inamespace\x11\x00\x00\x03\x00\x01\x00\x15\xa2Dargs\xa1Inamespace\x19\x00\x00\x03\x00\x01\x00\x12JnamespacesDnameHlistkeys\x18\x00\x00\x01\x00\x01\x00\x12IbookmarksDnameHlistkeys
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x03\x00\x02\x01\x92Hidentity
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x03\x00\x02\x041\xa1FstatusBok
- s> \r\n
- s> 28\r\n
- s> \x00\x00\x03\x00\x02\x041\xa3Ibookmarks@Jnamespaces@Fphases@
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x03\x00\x02\x002
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x01\x00\x02\x041\xa1FstatusBok
- s> \r\n
- s> 9\r\n
- s> \x01\x00\x00\x01\x00\x02\x041\xa0
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x01\x00\x02\x002
- s> \r\n
- s> 0\r\n
- s> \r\n
-
-Restart server to disable read-write access
-
- $ killdaemons.py
- $ cat > server/.hg/hgrc << EOF
- > [experimental]
- > web.apiserver = true
- > web.api.debugreflect = true
- > web.api.http-v2 = true
- > [web]
- > push_ssl = false
- > EOF
-
- $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-Attempting to run a read-write command via multirequest on read-only URL is not allowed
-
- $ sendhttpraw << EOF
- > httprequest POST api/$HTTPV2/ro/multirequest
- > accept: $MEDIATYPE
- > content-type: $MEDIATYPE
- > user-agent: test
- > frame 1 1 stream-begin command-request new cbor:{b'name': b'pushkey'}
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/multirequest HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> user-agent: test\r\n
- s> content-length: 22\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> \x0e\x00\x00\x01\x00\x01\x01\x11\xa1DnameGpushkey
- s> makefile('rb', None)
- s> HTTP/1.1 403 Forbidden\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 52\r\n
- s> \r\n
- s> insufficient permissions to execute command: pushkey
-
-Defining an invalid content encoding results in warning
-
- $ hg --config experimental.httppeer.v2-encoder-order=identity,badencoder --verbose debugwireproto --nologhandshake --peer http2 http://$LOCALIP:$HGPORT/ << EOF
- > command heads
- > EOF
- creating http peer for wire protocol version 2
- sending heads command
- wire protocol version 2 encoder referenced in config (badencoder) is not known; ignoring
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/heads HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> content-length: 56\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> \x1c\x00\x00\x01\x00\x01\x01\x82\xa1Pcontentencodings\x81Hidentity\x0c\x00\x00\x01\x00\x01\x00\x11\xa1DnameEheads
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x01\x00\x02\x01\x92
- s> Hidentity
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x01\x00\x02\x041
- s> \xa1FstatusBok
- s> \r\n
- s> 1e\r\n
- s> \x16\x00\x00\x01\x00\x02\x041
- s> \x81T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x01\x00\x02\x002
- s> \r\n
- s> 0\r\n
- s> \r\n
- response: [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
-
-#if zstd
-
- $ hg --verbose debugwireproto --nologhandshake --peer http2 http://$LOCALIP:$HGPORT/ << EOF
- > command heads
- > EOF
- creating http peer for wire protocol version 2
- sending heads command
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/heads HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> content-length: 70\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> *\x00\x00\x01\x00\x01\x01\x82\xa1Pcontentencodings\x83Hzstd-8mbDzlibHidentity\x0c\x00\x00\x01\x00\x01\x00\x11\xa1DnameEheads
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x01\x00\x02\x01\x92
- s> Hzstd-8mb
- s> \r\n
- s> 25\r\n
- s> \x1d\x00\x00\x01\x00\x02\x042
- s> (\xb5/\xfd\x00X\xa4\x00\x00p\xa1FstatusBok\x81T\x00\x01\x00\tP\x02
- s> \r\n
- s> 0\r\n
- s> \r\n
- response: [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
-
-#endif
-
- $ cat error.log
--- a/tests/test-http-api.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,299 +0,0 @@
-#require no-chg
-
- $ send() {
- > hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT/
- > }
-
- $ hg init server
- $ hg -R server serve -p $HGPORT -d --pid-file hg.pid
- $ cat hg.pid > $DAEMON_PIDS
-
-Request to /api fails unless web.apiserver is enabled
-
- $ get-with-headers.py $LOCALIP:$HGPORT api
- 400 no such method: api
-
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
- <head>
- <link rel="icon" href="/static/hgicon.png" type="image/png" />
- <meta name="robots" content="index, nofollow" />
- <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
- <script type="text/javascript" src="/static/mercurial.js"></script>
-
- <title>$TESTTMP/server: error</title>
- </head>
- <body>
-
- <div class="container">
- <div class="menu">
- <div class="logo">
- <a href="https://mercurial-scm.org/">
- <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
- </div>
- <ul>
- <li><a href="/shortlog">log</a></li>
- <li><a href="/graph">graph</a></li>
- <li><a href="/tags">tags</a></li>
- <li><a href="/bookmarks">bookmarks</a></li>
- <li><a href="/branches">branches</a></li>
- </ul>
- <ul>
- <li><a href="/help">help</a></li>
- </ul>
- </div>
-
- <div class="main">
-
- <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
- <h3>error</h3>
-
-
- <form class="search" action="/log">
-
- <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
- <div id="hint">Find changesets by keywords (author, files, the commit message), revision
- number or hash, or <a href="/help/revsets">revset expression</a>.</div>
- </form>
-
- <div class="description">
- <p>
- An error occurred while processing your request:
- </p>
- <p>
- no such method: api
- </p>
- </div>
- </div>
- </div>
-
-
-
- </body>
- </html>
-
- [1]
-
- $ get-with-headers.py $LOCALIP:$HGPORT api/
- 400 no such method: api
-
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
- <head>
- <link rel="icon" href="/static/hgicon.png" type="image/png" />
- <meta name="robots" content="index, nofollow" />
- <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
- <script type="text/javascript" src="/static/mercurial.js"></script>
-
- <title>$TESTTMP/server: error</title>
- </head>
- <body>
-
- <div class="container">
- <div class="menu">
- <div class="logo">
- <a href="https://mercurial-scm.org/">
- <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
- </div>
- <ul>
- <li><a href="/shortlog">log</a></li>
- <li><a href="/graph">graph</a></li>
- <li><a href="/tags">tags</a></li>
- <li><a href="/bookmarks">bookmarks</a></li>
- <li><a href="/branches">branches</a></li>
- </ul>
- <ul>
- <li><a href="/help">help</a></li>
- </ul>
- </div>
-
- <div class="main">
-
- <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
- <h3>error</h3>
-
-
- <form class="search" action="/log">
-
- <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
- <div id="hint">Find changesets by keywords (author, files, the commit message), revision
- number or hash, or <a href="/help/revsets">revset expression</a>.</div>
- </form>
-
- <div class="description">
- <p>
- An error occurred while processing your request:
- </p>
- <p>
- no such method: api
- </p>
- </div>
- </div>
- </div>
-
-
-
- </body>
- </html>
-
- [1]
-
-Restart server with support for API server
-
- $ killdaemons.py
- $ cat > server/.hg/hgrc << EOF
- > [experimental]
- > web.apiserver = true
- > EOF
-
- $ hg -R server serve -p $HGPORT -d --pid-file hg.pid
- $ cat hg.pid > $DAEMON_PIDS
-
-/api lists available APIs (empty since none are available by default)
-
- $ send << EOF
- > httprequest GET api
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /api HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 100\r\n
- s> \r\n
- s> APIs can be accessed at /api/<name>, where <name> can be one of the following:\n
- s> \n
- s> (no available APIs)\n
-
- $ send << EOF
- > httprequest GET api/
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /api/ HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 100\r\n
- s> \r\n
- s> APIs can be accessed at /api/<name>, where <name> can be one of the following:\n
- s> \n
- s> (no available APIs)\n
-
-Accessing an unknown API yields a 404
-
- $ send << EOF
- > httprequest GET api/unknown
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /api/unknown HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 404 Not Found\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 33\r\n
- s> \r\n
- s> Unknown API: unknown\n
- s> Known APIs:
-
-Accessing a known but not enabled API yields a different error
-
- $ send << EOF
- > httprequest GET api/exp-http-v2-0003
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /api/exp-http-v2-0003 HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 404 Not Found\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 33\r\n
- s> \r\n
- s> API exp-http-v2-0003 not enabled\n
-
-Restart server with support for HTTP v2 API
-
- $ killdaemons.py
- $ cat > server/.hg/hgrc << EOF
- > [experimental]
- > web.apiserver = true
- > web.api.http-v2 = true
- > EOF
-
- $ hg -R server serve -p $HGPORT -d --pid-file hg.pid
- $ cat hg.pid > $DAEMON_PIDS
-
-/api lists the HTTP v2 protocol as available
-
- $ send << EOF
- > httprequest GET api
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /api HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 96\r\n
- s> \r\n
- s> APIs can be accessed at /api/<name>, where <name> can be one of the following:\n
- s> \n
- s> exp-http-v2-0003
-
- $ send << EOF
- > httprequest GET api/
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /api/ HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 96\r\n
- s> \r\n
- s> APIs can be accessed at /api/<name>, where <name> can be one of the following:\n
- s> \n
- s> exp-http-v2-0003
--- a/tests/test-http-protocol.t Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-http-protocol.t Tue Dec 07 16:44:22 2021 +0100
@@ -252,121 +252,6 @@
s> bookmarks\t\n
s> namespaces\t\n
s> phases\t
-
-Client with HTTPv2 enabled advertises that and gets old capabilities response from old server
-
- $ hg --config experimental.httppeer.advertise-v2=true --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
- > command heads
- > EOF
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
- s> x-hgproto-1: cbor\r\n
- s> x-hgupgrade-1: exp-http-v2-0003\r\n
- s> accept: application/mercurial-0.1\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 Script output follows\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-0.1\r\n
- s> Content-Length: *\r\n (glob)
- s> \r\n
- s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- sending heads command
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=heads HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> vary: X-HgProto-1\r\n
- s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
- s> accept: application/mercurial-0.1\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 Script output follows\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-0.1\r\n
- s> Content-Length: 41\r\n
- s> \r\n
- s> 0000000000000000000000000000000000000000\n
- response: [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ killdaemons.py
- $ enablehttpv2 empty
- $ hg --config server.compressionengines=zlib -R empty serve -p $HGPORT -d --pid-file hg.pid
- $ cat hg.pid > $DAEMON_PIDS
-
-Client with HTTPv2 enabled automatically upgrades if the server supports it
-
- $ hg --config experimental.httppeer.advertise-v2=true --config experimental.httppeer.v2-encoder-order=identity --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
- > command heads
- > EOF
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
- s> x-hgproto-1: cbor\r\n
- s> x-hgupgrade-1: exp-http-v2-0003\r\n
- s> accept: application/mercurial-0.1\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-cbor\r\n
- s> Content-Length: *\r\n (glob)
- s> \r\n
- s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0003\xa4Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1LsparserevlogNv1capabilitiesY\x01\xe4batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- sending heads command
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/heads HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> content-length: 56\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> \x1c\x00\x00\x01\x00\x01\x01\x82\xa1Pcontentencodings\x81Hidentity\x0c\x00\x00\x01\x00\x01\x00\x11\xa1DnameEheads
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x01\x00\x02\x01\x92
- s> Hidentity
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x01\x00\x02\x041
- s> \xa1FstatusBok
- s> \r\n
- s> 1e\r\n
- s> \x16\x00\x00\x01\x00\x02\x041
- s> \x81T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x01\x00\x02\x002
- s> \r\n
- s> 0\r\n
- s> \r\n
- response: [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
-
$ killdaemons.py
HTTP client follows HTTP redirect on handshake to new repo
--- a/tests/test-largefiles-wireproto.t Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-largefiles-wireproto.t Tue Dec 07 16:44:22 2021 +0100
@@ -1,13 +1,3 @@
-#testcases sshv1 sshv2
-
-#if sshv2
- $ cat >> $HGRCPATH << EOF
- > [experimental]
- > sshpeer.advertise-v2 = true
- > sshserver.support-v2 = true
- > EOF
-#endif
-
This file contains testcases that tend to be related to the wire protocol part
of largefiles.
--- a/tests/test-pull-network.t Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-pull-network.t Tue Dec 07 16:44:22 2021 +0100
@@ -1,15 +1,5 @@
#require serve
-#testcases sshv1 sshv2
-
-#if sshv2
- $ cat >> $HGRCPATH << EOF
- > [experimental]
- > sshpeer.advertise-v2 = true
- > sshserver.support-v2 = true
- > EOF
-#endif
-
$ hg init test
$ cd test
--- a/tests/test-ssh-bundle1.t Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-ssh-bundle1.t Tue Dec 07 16:44:22 2021 +0100
@@ -1,16 +1,6 @@
This test is a duplicate of 'test-http.t' feel free to factor out
parts that are not bundle1/bundle2 specific.
-#testcases sshv1 sshv2
-
-#if sshv2
- $ cat >> $HGRCPATH << EOF
- > [experimental]
- > sshpeer.advertise-v2 = true
- > sshserver.support-v2 = true
- > EOF
-#endif
-
$ cat << EOF >> $HGRCPATH
> [devel]
> # This test is dedicated to interaction through old bundle
@@ -483,15 +473,13 @@
$ hg pull --debug ssh://user@dummy/remote
pulling from ssh://user@dummy/remote
running .* ".*[/\\]dummyssh" ['"]user@dummy['"] ['"]hg -R remote serve --stdio['"] (re)
- sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
sending hello command
sending between command
- remote: 444 (sshv1 no-rust !)
- remote: 463 (sshv1 rust !)
- protocol upgraded to exp-ssh-v2-0003 (sshv2 !)
+ remote: 444 (no-rust !)
+ remote: 463 (rust !)
remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-rust !)
remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,persistent-nodemap,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (rust !)
- remote: 1 (sshv1 !)
+ remote: 1
sending protocaps command
preparing listkeys for "bookmarks"
sending listkeys command
--- a/tests/test-ssh-clone-r.t Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-ssh-clone-r.t Tue Dec 07 16:44:22 2021 +0100
@@ -1,15 +1,5 @@
This test tries to exercise the ssh functionality with a dummy script
-#testcases sshv1 sshv2
-
-#if sshv2
- $ cat >> $HGRCPATH << EOF
- > [experimental]
- > sshpeer.advertise-v2 = true
- > sshserver.support-v2 = true
- > EOF
-#endif
-
creating 'remote' repo
$ hg init remote
--- a/tests/test-ssh-proto-unbundle.t Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-ssh-proto-unbundle.t Tue Dec 07 16:44:22 2021 +0100
@@ -5,13 +5,6 @@
> use-persistent-nodemap = no
> EOF
- $ cat > hgrc-sshv2 << EOF
- > %include $HGRCPATH
- > [experimental]
- > sshpeer.advertise-v2 = true
- > sshserver.support-v2 = true
- > EOF
-
$ debugwireproto() {
> commands=`cat -`
> echo 'testing ssh1'
@@ -20,12 +13,6 @@
> if [ -n "$1" ]; then
> hg --config extensions.strip= strip --no-backup -r "all() - ::${tip}"
> fi
- > echo ""
- > echo 'testing ssh2'
- > echo "${commands}" | HGRCPATH=$TESTTMP/hgrc-sshv2 hg --verbose debugwireproto --localssh --noreadstderr
- > if [ -n "$1" ]; then
- > hg --config extensions.strip= strip --no-backup -r "all() - ::${tip}"
- > fi
> }
Generate some bundle files
@@ -103,56 +90,6 @@
e> read(-1) -> 115:
e> abort: incompatible Mercurial client; bundle2 required\n
e> (see https://www.mercurial-scm.org/wiki/IncompatibleClient)\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 0
- result: 0
- remote output:
- e> read(-1) -> 115:
- e> abort: incompatible Mercurial client; bundle2 required\n
- e> (see https://www.mercurial-scm.org/wiki/IncompatibleClient)\n
$ cd ..
@@ -287,61 +224,6 @@
e> transaction abort!\n
e> rollback completed\n
e> abort: pretxnchangegroup.fail hook failed\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 0
- result: 0
- remote output:
- e> read(-1) -> 151:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> ui.write 1 line\n
- e> transaction abort!\n
- e> rollback completed\n
- e> abort: pretxnchangegroup.fail hook failed\n
And a variation that writes multiple lines using ui.write
@@ -412,62 +294,6 @@
e> transaction abort!\n
e> rollback completed\n
e> abort: pretxnchangegroup.fail hook failed\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 0
- result: 0
- remote output:
- e> read(-1) -> 173:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> ui.write 2 lines 1\n
- e> ui.write 2 lines 2\n
- e> transaction abort!\n
- e> rollback completed\n
- e> abort: pretxnchangegroup.fail hook failed\n
And a variation that does a ui.flush() after writing output
@@ -537,61 +363,6 @@
e> transaction abort!\n
e> rollback completed\n
e> abort: pretxnchangegroup.fail hook failed\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 0
- result: 0
- remote output:
- e> read(-1) -> 157:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> ui.write 1 line flush\n
- e> transaction abort!\n
- e> rollback completed\n
- e> abort: pretxnchangegroup.fail hook failed\n
Multiple writes + flush
@@ -662,62 +433,6 @@
e> transaction abort!\n
e> rollback completed\n
e> abort: pretxnchangegroup.fail hook failed\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 0
- result: 0
- remote output:
- e> read(-1) -> 161:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> ui.write 1st\n
- e> ui.write 2nd\n
- e> transaction abort!\n
- e> rollback completed\n
- e> abort: pretxnchangegroup.fail hook failed\n
ui.write() + ui.write_err() output is captured
@@ -790,64 +505,7 @@
e> transaction abort!\n
e> rollback completed\n
e> abort: pretxnchangegroup.fail hook failed\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 0
- result: 0
- remote output:
- e> read(-1) -> 187:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> ui.write 1\n
- e> ui.write_err 1\n
- e> ui.write 2\n
- e> ui.write_err 2\n
- e> transaction abort!\n
- e> rollback completed\n
- e> abort: pretxnchangegroup.fail hook failed\n
+
print() output is captured
@@ -917,61 +575,6 @@
e> transaction abort!\n
e> rollback completed\n
e> abort: pretxnchangegroup.fail hook failed\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 0
- result: 0
- remote output:
- e> read(-1) -> 148:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> printed line\n
- e> transaction abort!\n
- e> rollback completed\n
- e> abort: pretxnchangegroup.fail hook failed\n
Mixed print() and ui.write() are both captured
@@ -1044,64 +647,6 @@
e> transaction abort!\n
e> rollback completed\n
e> abort: pretxnchangegroup.fail hook failed\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 0
- result: 0
- remote output:
- e> read(-1) -> 173:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> print 1\n
- e> ui.write 1\n
- e> print 2\n
- e> ui.write 2\n
- e> transaction abort!\n
- e> rollback completed\n
- e> abort: pretxnchangegroup.fail hook failed\n
print() to stdout and stderr both get captured
@@ -1174,64 +719,6 @@
e> transaction abort!\n
e> rollback completed\n
e> abort: pretxnchangegroup.fail hook failed\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 0
- result: 0
- remote output:
- e> read(-1) -> 171:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> stdout 1\n
- e> stderr 1\n
- e> stdout 2\n
- e> stderr 2\n
- e> transaction abort!\n
- e> rollback completed\n
- e> abort: pretxnchangegroup.fail hook failed\n
Shell hook writing to stdout has output captured
@@ -1308,63 +795,6 @@
e> transaction abort!\n
e> rollback completed\n
e> abort: pretxnchangegroup.fail hook exited with status 1\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 0
- result: 0
- remote output:
- e> read(-1) -> 167:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> stdout 1\n
- e> stdout 2\n
- e> transaction abort!\n
- e> rollback completed\n
- e> abort: pretxnchangegroup.fail hook exited with status 1\n
-
Shell hook writing to stderr has output captured
$ cat > $TESTTMP/hook.sh << EOF
@@ -1435,63 +865,6 @@
e> transaction abort!\n
e> rollback completed\n
e> abort: pretxnchangegroup.fail hook exited with status 1\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 0
- result: 0
- remote output:
- e> read(-1) -> 167:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> stderr 1\n
- e> stderr 2\n
- e> transaction abort!\n
- e> rollback completed\n
- e> abort: pretxnchangegroup.fail hook exited with status 1\n
-
Shell hook writing to stdout and stderr has output captured
$ cat > $TESTTMP/hook.sh << EOF
@@ -1566,65 +939,6 @@
e> transaction abort!\n
e> rollback completed\n
e> abort: pretxnchangegroup.fail hook exited with status 1\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 0
- result: 0
- remote output:
- e> read(-1) -> 185:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> stdout 1\n
- e> stderr 1\n
- e> stdout 2\n
- e> stderr 2\n
- e> transaction abort!\n
- e> rollback completed\n
- e> abort: pretxnchangegroup.fail hook exited with status 1\n
-
Shell and Python hooks writing to stdout and stderr have output captured
$ cat > $TESTTMP/hook.sh << EOF
@@ -1709,69 +1023,6 @@
e> transaction abort!\n
e> rollback completed\n
e> abort: pretxnchangegroup.b hook failed\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 0
- result: 0
- remote output:
- e> read(-1) -> 228:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> shell stdout 1\n
- e> shell stderr 1\n
- e> shell stdout 2\n
- e> shell stderr 2\n
- e> stdout 1\n
- e> stderr 1\n
- e> stdout 2\n
- e> stderr 2\n
- e> transaction abort!\n
- e> rollback completed\n
- e> abort: pretxnchangegroup.b hook failed\n
-
$ cd ..
Pushing a bundle1 with no output
@@ -1837,59 +1088,6 @@
e> adding manifests\n
e> adding file changes\n
e> added 1 changesets with 1 changes to 1 files\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 1
- result: 1
- remote output:
- e> read(-1) -> 100:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> added 1 changesets with 1 changes to 1 files\n
-
$ cd ..
Pushing a bundle1 with ui.write() and ui.write_err()
@@ -1971,59 +1169,3 @@
e> ui.write 2\n
e> ui.write_err 2\n
e> added 1 changesets with 1 changes to 1 files\n
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending unbundle command
- i> write(9) -> 9:
- i> unbundle\n
- i> write(9) -> 9:
- i> heads 10\n
- i> write(10) -> 10: 666f726365
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- i> write(4) -> 4:
- i> 426\n
- i> write(426) -> 426:
- i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
- i> test\n
- i> 0 0\n
- i> foo\n
- i> \n
- i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
- i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
- i> \x00\x00\x00\x00\x00\x00\x00\x00
- i> write(2) -> 2:
- i> 0\n
- i> flush() -> None
- o> readline() -> 2:
- o> 0\n
- o> readline() -> 2:
- o> 1\n
- o> read(1) -> 1: 1
- result: 1
- remote output:
- e> read(-1) -> 152:
- e> adding changesets\n
- e> adding manifests\n
- e> adding file changes\n
- e> ui.write 1\n
- e> ui.write_err 1\n
- e> ui.write 2\n
- e> ui.write_err 2\n
- e> added 1 changesets with 1 changes to 1 files\n
--- a/tests/test-ssh-proto.t Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-ssh-proto.t Tue Dec 07 16:44:22 2021 +0100
@@ -7,13 +7,6 @@
> use-persistent-nodemap = no
> EOF
- $ cat > hgrc-sshv2 << EOF
- > %include $HGRCPATH
- > [experimental]
- > sshpeer.advertise-v2 = true
- > sshserver.support-v2 = true
- > EOF
-
Helper function to run protocol tests against multiple protocol versions.
This is easier than using #testcases because managing differences between
protocols with inline conditional output is hard to read.
@@ -22,9 +15,6 @@
> commands=`cat -`
> echo 'testing ssh1'
> echo "${commands}" | hg --verbose debugwireproto --localssh
- > echo ""
- > echo 'testing ssh2'
- > echo "${commands}" | HGRCPATH=$TESTTMP/hgrc-sshv2 hg --verbose debugwireproto --localssh
> }
$ cat >> $HGRCPATH << EOF
@@ -54,9 +44,6 @@
$ hg debugwireproto --localssh --peer ssh1 << EOF
> EOF
creating ssh peer for wire protocol version 1
- $ hg debugwireproto --localssh --peer ssh2 << EOF
- > EOF
- creating ssh peer for wire protocol version 2
Test a normal behaving server, for sanity
@@ -916,410 +903,6 @@
o> readline() -> 4:
o> 444\n
-Send an upgrade request to a server that doesn't support that command
-
- $ hg debugwireproto --localssh --peer raw << EOF
- > raw
- > upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=irrelevant1%2Cirrelevant2\n
- > readline
- > raw
- > hello\n
- > between\n
- > pairs 81\n
- > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- > readline
- > readline
- > readline
- > readline
- > EOF
- using raw connection to peer
- i> write(77) -> 77:
- i> upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=irrelevant1%2Cirrelevant2\n
- o> readline() -> 2:
- o> 0\n
- i> write(104) -> 104:
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- o> readline() -> 4:
- o> 444\n
- o> readline() -> 444:
- o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
- o> readline() -> 2:
- o> 1\n
- o> readline() -> 1:
- o> \n
-
- $ cd ..
-
- $ hg --config experimental.sshpeer.advertise-v2=true --debug debugpeer ssh://user@dummy/server
- running .* ".*[/\\]dummyssh" ['"]user@dummy['"] ['"]hg -R server serve --stdio['"] (re)
- sending upgrade request: * proto=exp-ssh-v2-0003 (glob)
- devel-peer-request: hello+between
- devel-peer-request: pairs: 81 bytes
- sending hello command
- sending between command
- remote: 0
- remote: 444
- remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- remote: 1
- devel-peer-request: protocaps
- devel-peer-request: caps: * bytes (glob)
- sending protocaps command
- url: ssh://user@dummy/server
- local: no
- pushable: yes
-
-Enable version 2 support on server. We need to do this in hgrc because we can't
-use --config with `hg serve --stdio`.
-
- $ cat >> server/.hg/hgrc << EOF
- > [experimental]
- > sshserver.support-v2 = true
- > EOF
-
-Send an upgrade request to a server that supports upgrade
-
- $ cd server
-
- $ hg debugwireproto --localssh --peer raw << EOF
- > raw
- > upgrade this-is-some-token proto=exp-ssh-v2-0003\n
- > hello\n
- > between\n
- > pairs 81\n
- > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- > readline
- > readline
- > readline
- > EOF
- using raw connection to peer
- i> write(153) -> 153:
- i> upgrade this-is-some-token proto=exp-ssh-v2-0003\n
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- o> readline() -> 44:
- o> upgraded this-is-some-token exp-ssh-v2-0003\n
- o> readline() -> 4:
- o> 443\n
- o> readline() -> 444:
- o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
-
- $ cd ..
-
- $ hg --config experimental.sshpeer.advertise-v2=true --debug debugpeer ssh://user@dummy/server
- running .* ".*[/\\]dummyssh" ['"]user@dummy['"] ['"]hg -R server serve --stdio['"] (re)
- sending upgrade request: * proto=exp-ssh-v2-0003 (glob)
- devel-peer-request: hello+between
- devel-peer-request: pairs: 81 bytes
- sending hello command
- sending between command
- protocol upgraded to exp-ssh-v2-0003
- remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- devel-peer-request: protocaps
- devel-peer-request: caps: * bytes (glob)
- sending protocaps command
- url: ssh://user@dummy/server
- local: no
- pushable: yes
-
-Verify the peer has capabilities
-
- $ hg --config experimental.sshpeer.advertise-v2=true --debug debugcapabilities ssh://user@dummy/server
- running .* ".*[/\\]dummyssh" ['"]user@dummy['"] ['"]hg -R server serve --stdio['"] (re)
- sending upgrade request: * proto=exp-ssh-v2-0003 (glob)
- devel-peer-request: hello+between
- devel-peer-request: pairs: 81 bytes
- sending hello command
- sending between command
- protocol upgraded to exp-ssh-v2-0003
- remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- devel-peer-request: protocaps
- devel-peer-request: caps: * bytes (glob)
- sending protocaps command
- Main capabilities:
- batch
- branchmap
- $USUAL_BUNDLE2_CAPS$
- changegroupsubset
- getbundle
- known
- lookup
- protocaps
- pushkey
- streamreqs=generaldelta,revlogv1,sparserevlog
- unbundle=HG10GZ,HG10BZ,HG10UN
- unbundlehash
- Bundle2 capabilities:
- HG20
- bookmarks
- changegroup
- 01
- 02
- checkheads
- related
- digests
- md5
- sha1
- sha512
- error
- abort
- unsupportedcontent
- pushraced
- pushkey
- hgtagsfnodes
- listkeys
- phases
- heads
- pushkey
- remote-changegroup
- http
- https
- stream
- v2
-
-Command after upgrade to version 2 is processed
-
- $ cd server
-
- $ hg debugwireproto --localssh --peer raw << EOF
- > raw
- > upgrade this-is-some-token proto=exp-ssh-v2-0003\n
- > hello\n
- > between\n
- > pairs 81\n
- > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- > readline
- > readline
- > readline
- > raw
- > hello\n
- > readline
- > readline
- > EOF
- using raw connection to peer
- i> write(153) -> 153:
- i> upgrade this-is-some-token proto=exp-ssh-v2-0003\n
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- o> readline() -> 44:
- o> upgraded this-is-some-token exp-ssh-v2-0003\n
- o> readline() -> 4:
- o> 443\n
- o> readline() -> 444:
- o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
- i> write(6) -> 6:
- i> hello\n
- o> readline() -> 4:
- o> 428\n
- o> readline() -> 428:
- o> capabilities: branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
-
-Multiple upgrades is not allowed
-
- $ hg debugwireproto --localssh --peer raw << EOF
- > raw
- > upgrade this-is-some-token proto=exp-ssh-v2-0003\n
- > hello\n
- > between\n
- > pairs 81\n
- > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- > readline
- > readline
- > readline
- > raw
- > upgrade another-token proto=irrelevant\n
- > hello\n
- > readline
- > readavailable
- > EOF
- using raw connection to peer
- i> write(153) -> 153:
- i> upgrade this-is-some-token proto=exp-ssh-v2-0003\n
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- o> readline() -> 44:
- o> upgraded this-is-some-token exp-ssh-v2-0003\n
- o> readline() -> 4:
- o> 443\n
- o> readline() -> 444:
- o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
- i> write(45) -> 45:
- i> upgrade another-token proto=irrelevant\n
- i> hello\n
- o> readline() -> 1:
- o> \n
- e> read(-1) -> 42:
- e> cannot upgrade protocols multiple times\n
- e> -\n
-
-Malformed upgrade request line (not exactly 3 space delimited tokens)
-
- $ hg debugwireproto --localssh --peer raw << EOF
- > raw
- > upgrade\n
- > readline
- > EOF
- using raw connection to peer
- i> write(8) -> 8:
- i> upgrade\n
- o> readline() -> 2:
- o> 0\n
-
- $ hg debugwireproto --localssh --peer raw << EOF
- > raw
- > upgrade token\n
- > readline
- > EOF
- using raw connection to peer
- i> write(14) -> 14:
- i> upgrade token\n
- o> readline() -> 2:
- o> 0\n
-
- $ hg debugwireproto --localssh --peer raw << EOF
- > raw
- > upgrade token foo=bar extra-token\n
- > readline
- > EOF
- using raw connection to peer
- i> write(34) -> 34:
- i> upgrade token foo=bar extra-token\n
- o> readline() -> 2:
- o> 0\n
-
-Upgrade request to unsupported protocol is ignored
-
- $ hg debugwireproto --localssh --peer raw << EOF
- > raw
- > upgrade this-is-some-token proto=unknown1,unknown2\n
- > readline
- > raw
- > hello\n
- > readline
- > readline
- > raw
- > between\n
- > pairs 81\n
- > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- > readline
- > readline
- > EOF
- using raw connection to peer
- i> write(51) -> 51:
- i> upgrade this-is-some-token proto=unknown1,unknown2\n
- o> readline() -> 2:
- o> 0\n
- i> write(6) -> 6:
- i> hello\n
- o> readline() -> 4:
- o> 444\n
- o> readline() -> 444:
- o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
- i> write(98) -> 98:
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- o> readline() -> 2:
- o> 1\n
- o> readline() -> 1:
- o> \n
-
-Upgrade request must be followed by hello + between
-
- $ hg debugwireproto --localssh --peer raw << EOF
- > raw
- > upgrade token proto=exp-ssh-v2-0003\n
- > invalid\n
- > readline
- > readavailable
- > EOF
- using raw connection to peer
- i> write(44) -> 44:
- i> upgrade token proto=exp-ssh-v2-0003\n
- i> invalid\n
- o> readline() -> 1:
- o> \n
- e> read(-1) -> 46:
- e> malformed handshake protocol: missing hello\n
- e> -\n
-
- $ hg debugwireproto --localssh --peer raw << EOF
- > raw
- > upgrade token proto=exp-ssh-v2-0003\n
- > hello\n
- > invalid\n
- > readline
- > readavailable
- > EOF
- using raw connection to peer
- i> write(50) -> 50:
- i> upgrade token proto=exp-ssh-v2-0003\n
- i> hello\n
- i> invalid\n
- o> readline() -> 1:
- o> \n
- e> read(-1) -> 48:
- e> malformed handshake protocol: missing between\n
- e> -\n
-
- $ hg debugwireproto --localssh --peer raw << EOF
- > raw
- > upgrade token proto=exp-ssh-v2-0003\n
- > hello\n
- > between\n
- > invalid\n
- > readline
- > readavailable
- > EOF
- using raw connection to peer
- i> write(58) -> 58:
- i> upgrade token proto=exp-ssh-v2-0003\n
- i> hello\n
- i> between\n
- i> invalid\n
- o> readline() -> 1:
- o> \n
- e> read(-1) -> 49:
- e> malformed handshake protocol: missing pairs 81\n
- e> -\n
-
-Legacy commands are not exposed to version 2 of protocol
-
-TODO re-enable these once we're back to actually using v2 commands
-
-$ hg --config experimental.sshpeer.advertise-v2=true debugwireproto --localssh << EOF
-> command branches
-> nodes 0000000000000000000000000000000000000000
-> EOF
-creating ssh peer from handshake results
-sending branches command
-response:
-
-$ hg --config experimental.sshpeer.advertise-v2=true debugwireproto --localssh << EOF
-> command changegroup
-> roots 0000000000000000000000000000000000000000
-> EOF
-creating ssh peer from handshake results
-sending changegroup command
-response:
-
-$ hg --config experimental.sshpeer.advertise-v2=true debugwireproto --localssh << EOF
-> command changegroupsubset
-> bases 0000000000000000000000000000000000000000
-> heads 0000000000000000000000000000000000000000
-> EOF
-creating ssh peer from handshake results
-sending changegroupsubset command
-response:
-
$ cd ..
Test listkeys for listing namespaces
@@ -1364,41 +947,6 @@
b'namespaces': b'',
b'phases': b''
}
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending listkeys command
- i> write(9) -> 9:
- i> listkeys\n
- i> write(13) -> 13:
- i> namespace 10\n
- i> write(10) -> 10: namespaces
- i> flush() -> None
- o> bufferedreadline() -> 3:
- o> 30\n
- o> bufferedread(30) -> 30:
- o> bookmarks\t\n
- o> namespaces\t\n
- o> phases\t
- response: {
- b'bookmarks': b'',
- b'namespaces': b'',
- b'phases': b''
- }
$ cd ..
@@ -1444,33 +992,6 @@
o> bufferedreadline() -> 2:
o> 0\n
response: {}
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending listkeys command
- i> write(9) -> 9:
- i> listkeys\n
- i> write(12) -> 12:
- i> namespace 9\n
- i> write(9) -> 9: bookmarks
- i> flush() -> None
- o> bufferedreadline() -> 2:
- o> 0\n
- response: {}
With a single bookmark set
@@ -1508,36 +1029,6 @@
response: {
b'bookA': b'68986213bd4485ea51533535e3fc9e78007a711f'
}
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending listkeys command
- i> write(9) -> 9:
- i> listkeys\n
- i> write(12) -> 12:
- i> namespace 9\n
- i> write(9) -> 9: bookmarks
- i> flush() -> None
- o> bufferedreadline() -> 3:
- o> 46\n
- o> bufferedread(46) -> 46: bookA\t68986213bd4485ea51533535e3fc9e78007a711f
- response: {
- b'bookA': b'68986213bd4485ea51533535e3fc9e78007a711f'
- }
With multiple bookmarks set
@@ -1578,39 +1069,6 @@
b'bookA': b'68986213bd4485ea51533535e3fc9e78007a711f',
b'bookB': b'1880f3755e2e52e3199e0ee5638128b08642f34d'
}
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending listkeys command
- i> write(9) -> 9:
- i> listkeys\n
- i> write(12) -> 12:
- i> namespace 9\n
- i> write(9) -> 9: bookmarks
- i> flush() -> None
- o> bufferedreadline() -> 3:
- o> 93\n
- o> bufferedread(93) -> 93:
- o> bookA\t68986213bd4485ea51533535e3fc9e78007a711f\n
- o> bookB\t1880f3755e2e52e3199e0ee5638128b08642f34d
- response: {
- b'bookA': b'68986213bd4485ea51533535e3fc9e78007a711f',
- b'bookB': b'1880f3755e2e52e3199e0ee5638128b08642f34d'
- }
Test pushkey for bookmarks
@@ -1657,43 +1115,6 @@
o> bufferedread(2) -> 2:
o> 1\n
response: True
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending pushkey command
- i> write(8) -> 8:
- i> pushkey\n
- i> write(6) -> 6:
- i> key 6\n
- i> write(6) -> 6: remote
- i> write(12) -> 12:
- i> namespace 9\n
- i> write(9) -> 9: bookmarks
- i> write(7) -> 7:
- i> new 40\n
- i> write(40) -> 40: 68986213bd4485ea51533535e3fc9e78007a711f
- i> write(6) -> 6:
- i> old 0\n
- i> flush() -> None
- o> bufferedreadline() -> 2:
- o> 2\n
- o> bufferedread(2) -> 2:
- o> 1\n
- response: True
$ hg bookmarks
bookA 0:68986213bd44
@@ -1742,36 +1163,6 @@
response: {
b'publishing': b'True'
}
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending listkeys command
- i> write(9) -> 9:
- i> listkeys\n
- i> write(12) -> 12:
- i> namespace 6\n
- i> write(6) -> 6: phases
- i> flush() -> None
- o> bufferedreadline() -> 3:
- o> 15\n
- o> bufferedread(15) -> 15: publishing\tTrue
- response: {
- b'publishing': b'True'
- }
Create some commits
@@ -1830,41 +1221,6 @@
b'c4750011d906c18ea2f0527419cbc1a544435150': b'1',
b'publishing': b'True'
}
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending listkeys command
- i> write(9) -> 9:
- i> listkeys\n
- i> write(12) -> 12:
- i> namespace 6\n
- i> write(6) -> 6: phases
- i> flush() -> None
- o> bufferedreadline() -> 4:
- o> 101\n
- o> bufferedread(101) -> 101:
- o> 20b8a89289d80036e6c4e87c2083e3bea1586637\t1\n
- o> c4750011d906c18ea2f0527419cbc1a544435150\t1\n
- o> publishing\tTrue
- response: {
- b'20b8a89289d80036e6c4e87c2083e3bea1586637': b'1',
- b'c4750011d906c18ea2f0527419cbc1a544435150': b'1',
- b'publishing': b'True'
- }
Single draft head
@@ -1905,39 +1261,6 @@
b'c4750011d906c18ea2f0527419cbc1a544435150': b'1',
b'publishing': b'True'
}
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending listkeys command
- i> write(9) -> 9:
- i> listkeys\n
- i> write(12) -> 12:
- i> namespace 6\n
- i> write(6) -> 6: phases
- i> flush() -> None
- o> bufferedreadline() -> 3:
- o> 58\n
- o> bufferedread(58) -> 58:
- o> c4750011d906c18ea2f0527419cbc1a544435150\t1\n
- o> publishing\tTrue
- response: {
- b'c4750011d906c18ea2f0527419cbc1a544435150': b'1',
- b'publishing': b'True'
- }
All public heads
@@ -1975,36 +1298,6 @@
response: {
b'publishing': b'True'
}
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending listkeys command
- i> write(9) -> 9:
- i> listkeys\n
- i> write(12) -> 12:
- i> namespace 6\n
- i> write(6) -> 6: phases
- i> flush() -> None
- o> bufferedreadline() -> 3:
- o> 15\n
- o> bufferedread(15) -> 15: publishing\tTrue
- response: {
- b'publishing': b'True'
- }
Setting public phase via pushkey
@@ -2054,44 +1347,6 @@
o> bufferedread(2) -> 2:
o> 1\n
response: True
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending pushkey command
- i> write(8) -> 8:
- i> pushkey\n
- i> write(7) -> 7:
- i> key 40\n
- i> write(40) -> 40: 7127240a084fd9dc86fe8d1f98e26229161ec82b
- i> write(12) -> 12:
- i> namespace 6\n
- i> write(6) -> 6: phases
- i> write(6) -> 6:
- i> new 1\n
- i> write(1) -> 1: 0
- i> write(6) -> 6:
- i> old 1\n
- i> write(1) -> 1: 1
- i> flush() -> None
- o> bufferedreadline() -> 2:
- o> 2\n
- o> bufferedread(2) -> 2:
- o> 1\n
- response: True
$ hg phase .
4: public
@@ -2160,40 +1415,3 @@
response #0: bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
response #1: bookA\t4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\nbookB\tbfebe6bd38eebc6f8202e419c1171268987ea6a6
response #2: 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\t1\nbfebe6bd38eebc6f8202e419c1171268987ea6a6\t1\npublishing\tTrue
-
- testing ssh2
- creating ssh peer from handshake results
- i> write(171) -> 171:
- i> upgrade * proto=exp-ssh-v2-0003\n (glob)
- i> hello\n
- i> between\n
- i> pairs 81\n
- i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
- i> flush() -> None
- o> readline() -> 62:
- o> upgraded * exp-ssh-v2-0003\n (glob)
- o> readline() -> 4:
- o> 443\n
- o> read(443) -> 443: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- o> read(1) -> 1:
- o> \n
- sending batch with 3 sub-commands
- i> write(6) -> 6:
- i> batch\n
- i> write(4) -> 4:
- i> * 0\n
- i> write(8) -> 8:
- i> cmds 61\n
- i> write(61) -> 61: heads ;listkeys namespace=bookmarks;listkeys namespace=phases
- i> flush() -> None
- o> bufferedreadline() -> 4:
- o> 278\n
- o> bufferedread(278) -> 278:
- o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
- o> ;bookA\t4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
- o> bookB\tbfebe6bd38eebc6f8202e419c1171268987ea6a6;4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\t1\n
- o> bfebe6bd38eebc6f8202e419c1171268987ea6a6\t1\n
- o> publishing\tTrue
- response #0: bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
- response #1: bookA\t4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\nbookB\tbfebe6bd38eebc6f8202e419c1171268987ea6a6
- response #2: 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\t1\nbfebe6bd38eebc6f8202e419c1171268987ea6a6\t1\npublishing\tTrue
--- a/tests/test-ssh.t Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/test-ssh.t Tue Dec 07 16:44:22 2021 +0100
@@ -1,13 +1,3 @@
-#testcases sshv1 sshv2
-
-#if sshv2
- $ cat >> $HGRCPATH << EOF
- > [experimental]
- > sshpeer.advertise-v2 = true
- > sshserver.support-v2 = true
- > EOF
-#endif
-
This test tries to exercise the ssh functionality with a dummy script
creating 'remote' repo
@@ -537,17 +527,15 @@
$ hg pull --debug ssh://user@dummy/remote --config devel.debug.peer-request=yes
pulling from ssh://user@dummy/remote
running .* ".*[/\\]dummyssh" ['"]user@dummy['"] ['"]hg -R remote serve --stdio['"] (re)
- sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
devel-peer-request: hello+between
devel-peer-request: pairs: 81 bytes
sending hello command
sending between command
- remote: 444 (sshv1 no-rust !)
- remote: 463 (sshv1 rust !)
- protocol upgraded to exp-ssh-v2-0003 (sshv2 !)
+ remote: 444 (no-rust !)
+ remote: 463 (rust !)
remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-rust !)
remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,persistent-nodemap,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (rust !)
- remote: 1 (sshv1 !)
+ remote: 1
devel-peer-request: protocaps
devel-peer-request: caps: * bytes (glob)
sending protocaps command
--- a/tests/test-wireproto-caching.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,468 +0,0 @@
- $ . $TESTDIR/wireprotohelpers.sh
-
-persistent-nodemap is not enabled by default. It is not relevant for this test so disable it.
-
- $ cat >> $HGRCPATH << EOF
- > [format]
- > use-persistent-nodemap = no
- > [extensions]
- > blackbox =
- > [blackbox]
- > track = simplecache
- > EOF
- $ hg init server
- $ enablehttpv2 server
- $ cd server
- $ cat >> .hg/hgrc << EOF
- > [extensions]
- > simplecache = $TESTDIR/wireprotosimplecache.py
- > EOF
-
- $ echo a0 > a
- $ echo b0 > b
- $ hg -q commit -A -m 'commit 0'
- $ echo a1 > a
- $ hg commit -m 'commit 1'
- $ echo b1 > b
- $ hg commit -m 'commit 2'
- $ echo a2 > a
- $ echo b2 > b
- $ hg commit -m 'commit 3'
-
- $ hg log -G -T '{rev}:{node} {desc}'
- @ 3:50590a86f3ff5d1e9a1624a7a6957884565cc8e8 commit 3
- |
- o 2:4d01eda50c6ac5f7e89cbe1880143a32f559c302 commit 2
- |
- o 1:4432d83626e8a98655f062ec1f2a43b07f7fbbb0 commit 1
- |
- o 0:3390ef850073fbc2f0dfff2244342c8e9229013a commit 0
-
-
- $ hg --debug debugindex -m
- rev linkrev nodeid p1 p2
- 0 0 992f4779029a3df8d0666d00bb924f69634e2641 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
- 1 1 a988fb43583e871d1ed5750ee074c6d840bbbfc8 992f4779029a3df8d0666d00bb924f69634e2641 0000000000000000000000000000000000000000
- 2 2 a8853dafacfca6fc807055a660d8b835141a3bb4 a988fb43583e871d1ed5750ee074c6d840bbbfc8 0000000000000000000000000000000000000000
- 3 3 3fe11dfbb13645782b0addafbe75a87c210ffddc a8853dafacfca6fc807055a660d8b835141a3bb4 0000000000000000000000000000000000000000
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-Performing the same request should result in same result, with 2nd response
-coming from cache.
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x99\x2f\x47\x79\x02\x9a\x3d\xf8\xd0\x66\x6d\x00\xbb\x92\x4f\x69\x63\x4e\x26\x41']
- > tree eval:b''
- > fields eval:[b'parents']
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- }
- ]
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x99\x2f\x47\x79\x02\x9a\x3d\xf8\xd0\x66\x6d\x00\xbb\x92\x4f\x69\x63\x4e\x26\x41']
- > tree eval:b''
- > fields eval:[b'parents']
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- }
- ]
-
-Sending different request doesn't yield cache hit.
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x99\x2f\x47\x79\x02\x9a\x3d\xf8\xd0\x66\x6d\x00\xbb\x92\x4f\x69\x63\x4e\x26\x41', b'\xa9\x88\xfb\x43\x58\x3e\x87\x1d\x1e\xd5\x75\x0e\xe0\x74\xc6\xd8\x40\xbb\xbf\xc8']
- > tree eval:b''
- > fields eval:[b'parents']
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 2
- },
- {
- b'node': b'\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- },
- {
- b'node': b'\xa9\x88\xfbCX>\x87\x1d\x1e\xd5u\x0e\xe0t\xc6\xd8@\xbb\xbf\xc8',
- b'parents': [
- b'\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- }
- ]
-
- $ cat .hg/blackbox.log
- *> cacher constructed for manifestdata (glob)
- *> cache miss for 47abb8efa5f01b8964d74917793ad2464db0fa2c (glob)
- *> storing cache entry for 47abb8efa5f01b8964d74917793ad2464db0fa2c (glob)
- *> cacher constructed for manifestdata (glob)
- *> cache hit for 47abb8efa5f01b8964d74917793ad2464db0fa2c (glob)
- *> cacher constructed for manifestdata (glob)
- *> cache miss for 37326a83e9843f15161fce9d1e92d06b795d5e8e (glob)
- *> storing cache entry for 37326a83e9843f15161fce9d1e92d06b795d5e8e (glob)
-
- $ cat error.log
-
- $ killdaemons.py
- $ rm .hg/blackbox.log
-
-Try with object caching mode
-
- $ cat >> .hg/hgrc << EOF
- > [simplecache]
- > cacheobjects = true
- > EOF
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x99\x2f\x47\x79\x02\x9a\x3d\xf8\xd0\x66\x6d\x00\xbb\x92\x4f\x69\x63\x4e\x26\x41']
- > tree eval:b''
- > fields eval:[b'parents']
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- }
- ]
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x99\x2f\x47\x79\x02\x9a\x3d\xf8\xd0\x66\x6d\x00\xbb\x92\x4f\x69\x63\x4e\x26\x41']
- > tree eval:b''
- > fields eval:[b'parents']
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- }
- ]
-
- $ cat .hg/blackbox.log
- *> cacher constructed for manifestdata (glob)
- *> cache miss for 47abb8efa5f01b8964d74917793ad2464db0fa2c (glob)
- *> storing cache entry for 47abb8efa5f01b8964d74917793ad2464db0fa2c (glob)
- *> cacher constructed for manifestdata (glob)
- *> cache hit for 47abb8efa5f01b8964d74917793ad2464db0fa2c (glob)
-
- $ cat error.log
-
- $ killdaemons.py
- $ rm .hg/blackbox.log
-
-A non-cacheable command does not instantiate cacher
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
- $ sendhttpv2peer << EOF
- > command capabilities
- > EOF
- creating http peer for wire protocol version 2
- sending capabilities command
- response: gen[
- {
- b'commands': {
- b'branchmap': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'capabilities': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'changesetdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'bookmarks',
- b'parents',
- b'phase',
- b'revision'
- ])
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filedata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'path': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filesdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'firstchangeset',
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'dict'
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 50000
- },
- b'heads': {
- b'args': {
- b'publiconly': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'known': {
- b'args': {
- b'nodes': {
- b'default': [],
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'listkeys': {
- b'args': {
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'lookup': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'manifestdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'tree': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 100000
- },
- b'pushkey': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- },
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- },
- b'new': {
- b'required': True,
- b'type': b'bytes'
- },
- b'old': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'push'
- ]
- },
- b'rawstorefiledata': {
- b'args': {
- b'files': {
- b'required': True,
- b'type': b'list'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- }
- },
- b'framingmediatypes': [
- b'application/mercurial-exp-framing-0006'
- ],
- b'pathfilterprefixes': set([
- b'path:',
- b'rootfilesin:'
- ]),
- b'rawrepoformats': [
- b'generaldelta',
- b'revlogv1',
- b'sparserevlog'
- ]
- }
- ]
-
- $ test -f .hg/blackbox.log
- [1]
-
-An error is not cached
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa']
- > tree eval:b''
- > fields eval:[b'parents']
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- abort: unknown node: \xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa (esc)
- [255]
-
- $ cat .hg/blackbox.log
- *> cacher constructed for manifestdata (glob)
- *> cache miss for 2cba2a7d0d1575fea2fe68f597e97a7c2ac2f705 (glob)
- *> cacher exiting due to error (glob)
-
- $ killdaemons.py
- $ rm .hg/blackbox.log
--- a/tests/test-wireproto-command-branchmap.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
- $ . $TESTDIR/wireprotohelpers.sh
-
- $ hg init server
- $ enablehttpv2 server
- $ cd server
- $ hg debugdrawdag << EOF
- > C D
- > |/
- > B
- > |
- > A
- > EOF
-
- $ hg up B
- 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg branch branch1
- marked working directory as branch branch1
- (branches are permanent and global, did you want a bookmark?)
- $ echo b1 > foo
- $ hg -q commit -A -m 'branch 1'
- $ hg up B
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg branch branch2
- marked working directory as branch branch2
- $ echo b2 > foo
- $ hg -q commit -A -m 'branch 2'
-
- $ hg log -T '{rev}:{node} {branch} {desc}\n'
- 5:224161c7589aa48fa83a48feff5e95b56ae327fc branch2 branch 2
- 4:b5faacdfd2633768cb3152336cc0953381266688 branch1 branch 1
- 3:be0ef73c17ade3fc89dc41701eb9fc3a91b58282 default D
- 2:26805aba1e600a82e93661149f2313866a221a7b default C
- 1:112478962961147124edd43549aedd1a335e44bf default B
- 0:426bada5c67598ca65036d57d9e4b64b0c1ce7a0 default A
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-No arguments returns something reasonable
-
- $ sendhttpv2peer << EOF
- > command branchmap
- > EOF
- creating http peer for wire protocol version 2
- sending branchmap command
- response: {
- b'branch1': [
- b'\xb5\xfa\xac\xdf\xd2c7h\xcb1R3l\xc0\x953\x81&f\x88'
- ],
- b'branch2': [
- b'"Aa\xc7X\x9a\xa4\x8f\xa8:H\xfe\xff^\x95\xb5j\xe3\'\xfc'
- ],
- b'default': [
- b'&\x80Z\xba\x1e`\n\x82\xe96a\x14\x9f#\x13\x86j"\x1a{',
- b'\xbe\x0e\xf7<\x17\xad\xe3\xfc\x89\xdcAp\x1e\xb9\xfc:\x91\xb5\x82\x82'
- ]
- }
-
- $ cat error.log
--- a/tests/test-wireproto-command-capabilities.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,762 +0,0 @@
-#require no-chg
-
- $ . $TESTDIR/wireprotohelpers.sh
-
-persistent-nodemap is not enabled by default. It is not relevant for this test so disable it.
-
- $ cat >> $HGRCPATH << EOF
- > [format]
- > use-persistent-nodemap = no
- > EOF
-
- $ hg init server
-
-zstd isn't present in plain builds. Make tests easier by removing
-zstd from the equation.
-
- $ cat >> server/.hg/hgrc << EOF
- > [server]
- > compressionengines = zlib
- > EOF
-
- $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-A normal capabilities request is serviced for version 1
-
- $ sendhttpraw << EOF
- > httprequest GET ?cmd=capabilities
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 Script output follows\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-0.1\r\n
- s> Content-Length: *\r\n (glob)
- s> \r\n
- s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
-
-A proper request without the API server enabled returns the legacy response
-
- $ sendhttpraw << EOF
- > httprequest GET ?cmd=capabilities
- > user-agent: test
- > x-hgupgrade-1: foo
- > x-hgproto-1: cbor
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> x-hgproto-1: cbor\r\n
- s> x-hgupgrade-1: foo\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 Script output follows\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-0.1\r\n
- s> Content-Length: *\r\n (glob)
- s> \r\n
- s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
-
-Restart with just API server enabled. This enables serving the new format.
-
- $ killdaemons.py
- $ cat error.log
-
- $ cat >> server/.hg/hgrc << EOF
- > [experimental]
- > web.apiserver = true
- > EOF
-
- $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-X-HgUpgrade-<N> without CBOR advertisement uses legacy response
-
- $ sendhttpraw << EOF
- > httprequest GET ?cmd=capabilities
- > user-agent: test
- > x-hgupgrade-1: foo bar
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> x-hgupgrade-1: foo bar\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 Script output follows\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-0.1\r\n
- s> Content-Length: *\r\n (glob)
- s> \r\n
- s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
-
-X-HgUpgrade-<N> without known serialization in X-HgProto-<N> uses legacy response
-
- $ sendhttpraw << EOF
- > httprequest GET ?cmd=capabilities
- > user-agent: test
- > x-hgupgrade-1: foo bar
- > x-hgproto-1: some value
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> x-hgproto-1: some value\r\n
- s> x-hgupgrade-1: foo bar\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 Script output follows\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-0.1\r\n
- s> Content-Length: *\r\n (glob)
- s> \r\n
- s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
-
-X-HgUpgrade-<N> + X-HgProto-<N> headers trigger new response format
-
- $ sendhttpraw << EOF
- > httprequest GET ?cmd=capabilities
- > user-agent: test
- > x-hgupgrade-1: foo bar
- > x-hgproto-1: cbor
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> x-hgproto-1: cbor\r\n
- s> x-hgupgrade-1: foo bar\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-cbor\r\n
- s> Content-Length: *\r\n (glob)
- s> \r\n
- s> \xa3GapibaseDapi/Dapis\xa0Nv1capabilitiesY\x01\xe4batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- cbor> [
- {
- b'apibase': b'api/',
- b'apis': {},
- b'v1capabilities': b'batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash'
- }
- ]
-
-Restart server to enable HTTPv2
-
- $ killdaemons.py
- $ enablehttpv2 server
- $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-Only requested API services are returned
-
- $ sendhttpraw << EOF
- > httprequest GET ?cmd=capabilities
- > user-agent: test
- > x-hgupgrade-1: foo bar
- > x-hgproto-1: cbor
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> x-hgproto-1: cbor\r\n
- s> x-hgupgrade-1: foo bar\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-cbor\r\n
- s> Content-Length: *\r\n (glob)
- s> \r\n
- s> \xa3GapibaseDapi/Dapis\xa0Nv1capabilitiesY\x01\xe4batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- cbor> [
- {
- b'apibase': b'api/',
- b'apis': {},
- b'v1capabilities': b'batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash'
- }
- ]
-
-Request for HTTPv2 service returns information about it
-
- $ sendhttpraw << EOF
- > httprequest GET ?cmd=capabilities
- > user-agent: test
- > x-hgupgrade-1: exp-http-v2-0003 foo bar
- > x-hgproto-1: cbor
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> x-hgproto-1: cbor\r\n
- s> x-hgupgrade-1: exp-http-v2-0003 foo bar\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-cbor\r\n
- s> Content-Length: *\r\n (glob)
- s> \r\n
- s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0003\xa4Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1LsparserevlogNv1capabilitiesY\x01\xe4batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- cbor> [
- {
- b'apibase': b'api/',
- b'apis': {
- b'exp-http-v2-0003': {
- b'commands': {
- b'branchmap': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'capabilities': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'changesetdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'bookmarks',
- b'parents',
- b'phase',
- b'revision'
- ])
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filedata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'path': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filesdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'firstchangeset',
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'dict'
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 50000
- },
- b'heads': {
- b'args': {
- b'publiconly': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'known': {
- b'args': {
- b'nodes': {
- b'default': [],
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'listkeys': {
- b'args': {
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'lookup': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'manifestdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'tree': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 100000
- },
- b'pushkey': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- },
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- },
- b'new': {
- b'required': True,
- b'type': b'bytes'
- },
- b'old': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'push'
- ]
- },
- b'rawstorefiledata': {
- b'args': {
- b'files': {
- b'required': True,
- b'type': b'list'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- }
- },
- b'framingmediatypes': [
- b'application/mercurial-exp-framing-0006'
- ],
- b'pathfilterprefixes': set([
- b'path:',
- b'rootfilesin:'
- ]),
- b'rawrepoformats': [
- b'generaldelta',
- b'revlogv1',
- b'sparserevlog'
- ]
- }
- },
- b'v1capabilities': b'batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash'
- }
- ]
-
-capabilities command returns expected info
-
- $ sendhttpv2peerhandshake << EOF
- > command capabilities
- > EOF
- creating http peer for wire protocol version 2
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
- s> x-hgproto-1: cbor\r\n
- s> x-hgupgrade-1: exp-http-v2-0003\r\n
- s> accept: application/mercurial-0.1\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-cbor\r\n
- s> Content-Length: *\r\n (glob)
- s> \r\n
- s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0003\xa4Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1LsparserevlogNv1capabilitiesY\x01\xe4batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- sending capabilities command
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> content-length: 63\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> \x1c\x00\x00\x01\x00\x01\x01\x82\xa1Pcontentencodings\x81Hidentity\x13\x00\x00\x01\x00\x01\x00\x11\xa1DnameLcapabilities
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x01\x00\x02\x01\x92
- s> Hidentity
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x01\x00\x02\x041
- s> \xa1FstatusBok
- s> \r\n
- s> 65e\r\n
- s> V\x06\x00\x01\x00\x02\x041
- s> \xa4Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1Lsparserevlog
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x01\x00\x02\x002
- s> \r\n
- s> 0\r\n
- s> \r\n
- response: gen[
- {
- b'commands': {
- b'branchmap': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'capabilities': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'changesetdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'bookmarks',
- b'parents',
- b'phase',
- b'revision'
- ])
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filedata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'path': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filesdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'firstchangeset',
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'dict'
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 50000
- },
- b'heads': {
- b'args': {
- b'publiconly': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'known': {
- b'args': {
- b'nodes': {
- b'default': [],
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'listkeys': {
- b'args': {
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'lookup': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'manifestdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'tree': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 100000
- },
- b'pushkey': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- },
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- },
- b'new': {
- b'required': True,
- b'type': b'bytes'
- },
- b'old': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'push'
- ]
- },
- b'rawstorefiledata': {
- b'args': {
- b'files': {
- b'required': True,
- b'type': b'list'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- }
- },
- b'framingmediatypes': [
- b'application/mercurial-exp-framing-0006'
- ],
- b'pathfilterprefixes': set([
- b'path:',
- b'rootfilesin:'
- ]),
- b'rawrepoformats': [
- b'generaldelta',
- b'revlogv1',
- b'sparserevlog'
- ]
- }
- ]
- (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ cat error.log
--- a/tests/test-wireproto-command-changesetdata.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,613 +0,0 @@
- $ . $TESTDIR/wireprotohelpers.sh
-
- $ hg init server
- $ enablehttpv2 server
- $ cd server
- $ cat >> .hg/hgrc << EOF
- > [phases]
- > publish = false
- > EOF
- $ echo a0 > a
- $ echo b0 > b
-
- $ hg -q commit -A -m 'commit 0'
-
- $ echo a1 > a
- $ echo b1 > b
- $ hg commit -m 'commit 1'
- $ echo b2 > b
- $ hg commit -m 'commit 2'
- $ hg phase --public -r .
-
- $ hg -q up -r 0
- $ echo a2 > a
- $ hg commit -m 'commit 3'
- created new head
-
- $ hg log -G -T '{rev}:{node} {desc}\n'
- @ 3:eae5f82c2e622368d27daecb76b7e393d0f24211 commit 3
- |
- | o 2:0bb8ad894a15b15380b2a2a5b183e20f2a4b28dd commit 2
- | |
- | o 1:7592917e1c3e82677cb0a4bc715ca25dd12d28c1 commit 1
- |/
- o 0:3390ef850073fbc2f0dfff2244342c8e9229013a commit 0
-
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-No arguments is an invalid request
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- abort: missing required arguments: revisions
- [255]
-
-Missing nodes for changesetexplicit results in error
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{b'type': b'changesetexplicit'}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- abort: nodes key not present in changesetexplicit revision specifier
- [255]
-
-changesetexplicitdepth requires nodes and depth keys
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{b'type': b'changesetexplicitdepth'}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- abort: nodes key not present in changesetexplicitdepth revision specifier
- [255]
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{b'type': b'changesetexplicitdepth', b'nodes': []}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- abort: depth key not present in changesetexplicitdepth revision specifier
- [255]
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{b'type': b'changesetexplicitdepth', b'depth': 42}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- abort: nodes key not present in changesetexplicitdepth revision specifier
- [255]
-
-changesetdagrange requires roots and heads keys
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{b'type': b'changesetdagrange'}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- abort: roots key not present in changesetdagrange revision specifier
- [255]
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{b'type': b'changesetdagrange', b'roots': []}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- abort: heads key not present in changesetdagrange revision specifier
- [255]
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{b'type': b'changesetdagrange', b'heads': [b'dummy']}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- abort: roots key not present in changesetdagrange revision specifier
- [255]
-
-Empty changesetdagrange heads results in an error
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{b'type': b'changesetdagrange', b'heads': [], b'roots': []}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- abort: heads key in changesetdagrange cannot be empty
- [255]
-
-Sending just dagrange heads sends all revisions
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{
- > b'type': b'changesetdagrange',
- > b'roots': [],
- > b'heads': [
- > b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd',
- > b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11',
- > ]}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 4
- },
- {
- b'node': b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:'
- },
- {
- b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1'
- },
- {
- b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd'
- },
- {
- b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
- }
- ]
-
-Sending root nodes limits what data is sent
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{
- > b'type': b'changesetdagrange',
- > b'roots': [b'\x33\x90\xef\x85\x00\x73\xfb\xc2\xf0\xdf\xff\x22\x44\x34\x2c\x8e\x92\x29\x01\x3a'],
- > b'heads': [
- > b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd',
- > ]}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 2
- },
- {
- b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1'
- },
- {
- b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd'
- }
- ]
-
-Requesting data on a single node by node works
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [b'\x33\x90\xef\x85\x00\x73\xfb\xc2\xf0\xdf\xff\x22\x44\x34\x2c\x8e\x92\x29\x01\x3a']}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:'
- }
- ]
-
-Specifying a noderange and nodes takes union
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[
- > {
- > b'type': b'changesetexplicit',
- > b'nodes': [b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11'],
- > },
- > {
- > b'type': b'changesetdagrange',
- > b'roots': [b'\x75\x92\x91\x7e\x1c\x3e\x82\x67\x7c\xb0\xa4\xbc\x71\x5c\xa2\x5d\xd1\x2d\x28\xc1'],
- > b'heads': [b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd'],
- > }]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 2
- },
- {
- b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
- },
- {
- b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd'
- }
- ]
-
-nodesdepth of 1 limits to exactly requested nodes
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{
- > b'type': b'changesetexplicitdepth',
- > b'nodes': [b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11'],
- > b'depth': 1}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
- }
- ]
-
-nodesdepth of 2 limits to first ancestor
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{
- > b'type': b'changesetexplicitdepth',
- > b'nodes': [b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11'],
- > b'depth': 2}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 2
- },
- {
- b'node': b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:'
- },
- {
- b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
- }
- ]
-
-nodesdepth with multiple nodes
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > revisions eval:[{
- > b'type': b'changesetexplicitdepth',
- > b'nodes': [b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11', b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd'],
- > b'depth': 2}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 4
- },
- {
- b'node': b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:'
- },
- {
- b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1'
- },
- {
- b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd'
- },
- {
- b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
- }
- ]
-
-Parents data is transferred upon request
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > fields eval:[b'parents']
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11',
- > ]}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11',
- b'parents': [
- b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- }
- ]
-
-Phase data is transferred upon request
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > fields eval:[b'phase']
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd',
- > ]}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd',
- b'phase': b'public'
- }
- ]
-
-Revision data is transferred upon request
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > fields eval:[b'revision']
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11',
- > ]}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 61
- ]
- ],
- b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
- },
- b'1b74476799ec8318045db759b1b4bcc9b839d0aa\ntest\n0 0\na\n\ncommit 3'
- ]
-
-Bookmarks key isn't present if no bookmarks data
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > fields eval:[b'bookmarks']
- > revisions eval:[{
- > b'type': b'changesetdagrange',
- > b'roots': [],
- > b'heads': [
- > b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd',
- > b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11',
- > ]}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 4
- },
- {
- b'node': b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:'
- },
- {
- b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1'
- },
- {
- b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd'
- },
- {
- b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
- }
- ]
-
-Bookmarks are sent when requested
-
- $ hg -R ../server bookmark -r 0bb8ad894a15b15380b2a2a5b183e20f2a4b28dd book-1
- $ hg -R ../server bookmark -r eae5f82c2e622368d27daecb76b7e393d0f24211 book-2
- $ hg -R ../server bookmark -r eae5f82c2e622368d27daecb76b7e393d0f24211 book-3
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > fields eval:[b'bookmarks']
- > revisions eval:[{
- > b'type': b'changesetdagrange',
- > b'roots': [],
- > b'heads': [
- > b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd',
- > b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11',
- > ]}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 4
- },
- {
- b'node': b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:'
- },
- {
- b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1'
- },
- {
- b'bookmarks': [
- b'book-1'
- ],
- b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd'
- },
- {
- b'bookmarks': [
- b'book-2',
- b'book-3'
- ],
- b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
- }
- ]
-
-Bookmarks are sent when we make a no-new-revisions request
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > fields eval:[b'bookmarks', b'revision']
- > revisions eval:[{
- > b'type': b'changesetdagrange',
- > b'roots': [b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11'],
- > b'heads': [
- > b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd',
- > b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11',
- > ]}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 2
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 63
- ]
- ],
- b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1'
- },
- b'7f144aea0ba742713887b564d57e9d12f12ff382\ntest\n0 0\na\nb\n\ncommit 1',
- {
- b'bookmarks': [
- b'book-1'
- ],
- b'fieldsfollowing': [
- [
- b'revision',
- 61
- ]
- ],
- b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd'
- },
- b'37f0a2d1c28ffe4b879109a7d1bbf8f07b3c763b\ntest\n0 0\nb\n\ncommit 2',
- {
- b'bookmarks': [
- b'book-2',
- b'book-3'
- ],
- b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
- }
- ]
-
-Multiple fields can be transferred
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > fields eval:[b'parents', b'revision']
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11',
- > ]}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 61
- ]
- ],
- b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11',
- b'parents': [
- b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- },
- b'1b74476799ec8318045db759b1b4bcc9b839d0aa\ntest\n0 0\na\n\ncommit 3'
- ]
-
-Base nodes have just their metadata (e.g. phase) transferred
-TODO this doesn't work
-
- $ sendhttpv2peer << EOF
- > command changesetdata
- > fields eval:[b'phase', b'parents', b'revision']
- > revisions eval:[{
- > b'type': b'changesetdagrange',
- > b'roots': [b'\x33\x90\xef\x85\x00\x73\xfb\xc2\xf0\xdf\xff\x22\x44\x34\x2c\x8e\x92\x29\x01\x3a'],
- > b'heads': [
- > b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd',
- > b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11',
- > ]}]
- > EOF
- creating http peer for wire protocol version 2
- sending changesetdata command
- response: gen[
- {
- b'totalitems': 3
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 63
- ]
- ],
- b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1',
- b'parents': [
- b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ],
- b'phase': b'public'
- },
- b'7f144aea0ba742713887b564d57e9d12f12ff382\ntest\n0 0\na\nb\n\ncommit 1',
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 61
- ]
- ],
- b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd',
- b'parents': [
- b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ],
- b'phase': b'public'
- },
- b'37f0a2d1c28ffe4b879109a7d1bbf8f07b3c763b\ntest\n0 0\nb\n\ncommit 2',
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 61
- ]
- ],
- b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11',
- b'parents': [
- b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ],
- b'phase': b'draft'
- },
- b'1b74476799ec8318045db759b1b4bcc9b839d0aa\ntest\n0 0\na\n\ncommit 3'
- ]
-
- $ cat error.log
--- a/tests/test-wireproto-command-filedata.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,364 +0,0 @@
- $ . $TESTDIR/wireprotohelpers.sh
-
- $ hg init server
- $ enablehttpv2 server
- $ cd server
- $ cat > a << EOF
- > a0
- > 00000000000000000000000000000000000000
- > 11111111111111111111111111111111111111
- > EOF
- $ echo b0 > b
- $ mkdir -p dir0/child0 dir0/child1 dir1
- $ echo c0 > dir0/c
- $ echo d0 > dir0/d
- $ echo e0 > dir0/child0/e
- $ echo f0 > dir0/child1/f
- $ hg -q commit -A -m 'commit 0'
-
- $ echo a1 >> a
- $ echo d1 > dir0/d
- $ hg commit -m 'commit 1'
- $ echo f1 > dir0/child1/f
- $ hg commit -m 'commit 2'
-
- $ hg -q up -r 0
- $ echo a2 >> a
- $ hg commit -m 'commit 3'
- created new head
-
-Create multiple heads introducing the same changeset
-
- $ hg -q up -r 0
- $ echo foo > dupe-file
- $ hg commit -Am 'dupe 1'
- adding dupe-file
- created new head
- $ hg -q up -r 0
- $ echo foo > dupe-file
- $ hg commit -Am 'dupe 2'
- adding dupe-file
- created new head
-
- $ hg log -G -T '{rev}:{node} {desc}\n'
- @ 5:732c3dd7bee94242de656000e5f458e7ccfe2828 dupe 2
- |
- | o 4:4334f10897d13c3e8beb4b636f7272b4ec2d0322 dupe 1
- |/
- | o 3:5ce944d7fece1252dae06c34422b573c191b9489 commit 3
- |/
- | o 2:b3c27db01410dae01e5485d425b1440078df540c commit 2
- | |
- | o 1:3ef5e551f219ba505481d34d6b0316b017fa3f00 commit 1
- |/
- o 0:91b232a2253ce0638496f67bdfd7a4933fb51b25 commit 0
-
-
- $ hg --debug debugindex a
- rev linkrev nodeid p1 p2
- 0 0 649d149df43d83882523b7fb1e6a3af6f1907b39 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
- 1 1 0a86321f1379d1a9ecd0579a22977af7a5acaf11 649d149df43d83882523b7fb1e6a3af6f1907b39 0000000000000000000000000000000000000000
- 2 3 7e5801b6d5f03a5a54f3c47b583f7567aad43e5b 649d149df43d83882523b7fb1e6a3af6f1907b39 0000000000000000000000000000000000000000
-
- $ hg --debug debugindex dir0/child0/e
- rev linkrev nodeid p1 p2
- 0 0 bbba6c06b30f443d34ff841bc985c4d0827c6be4 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
-
- $ hg --debug debugindex dupe-file
- rev linkrev nodeid p1 p2
- 0 4 2ed2a3912a0b24502043eae84ee4b279c18b90dd 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-Missing arguments is an error
-
- $ sendhttpv2peer << EOF
- > command filedata
- > EOF
- creating http peer for wire protocol version 2
- sending filedata command
- abort: missing required arguments: nodes, path
- [255]
-
- $ sendhttpv2peer << EOF
- > command filedata
- > nodes eval:[]
- > EOF
- creating http peer for wire protocol version 2
- sending filedata command
- abort: missing required arguments: path
- [255]
-
-Unknown node is an error
-
- $ sendhttpv2peer << EOF
- > command filedata
- > nodes eval:[b'\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa']
- > path eval:b'a'
- > EOF
- creating http peer for wire protocol version 2
- sending filedata command
- abort: unknown file node: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- [255]
-
-Fetching a single revision returns just metadata by default
-
- $ sendhttpv2peer << EOF
- > command filedata
- > nodes eval:[b'\x0a\x86\x32\x1f\x13\x79\xd1\xa9\xec\xd0\x57\x9a\x22\x97\x7a\xf7\xa5\xac\xaf\x11']
- > path eval:b'a'
- > EOF
- creating http peer for wire protocol version 2
- sending filedata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- }
- ]
-
-Requesting parents works
-
- $ sendhttpv2peer << EOF
- > command filedata
- > nodes eval:[b'\x0a\x86\x32\x1f\x13\x79\xd1\xa9\xec\xd0\x57\x9a\x22\x97\x7a\xf7\xa5\xac\xaf\x11']
- > path eval:b'a'
- > fields eval:[b'parents']
- > EOF
- creating http peer for wire protocol version 2
- sending filedata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11',
- b'parents': [
- b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- }
- ]
-
-Requesting revision data works
-(haveparents defaults to False, so fulltext is emitted)
-
- $ sendhttpv2peer << EOF
- > command filedata
- > nodes eval:[b'\x0a\x86\x32\x1f\x13\x79\xd1\xa9\xec\xd0\x57\x9a\x22\x97\x7a\xf7\xa5\xac\xaf\x11']
- > path eval:b'a'
- > fields eval:[b'revision']
- > EOF
- creating http peer for wire protocol version 2
- sending filedata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 84
- ]
- ],
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- b'a0\n00000000000000000000000000000000000000\n11111111111111111111111111111111111111\na1\n'
- ]
-
-haveparents=False should be same as above
-
- $ sendhttpv2peer << EOF
- > command filedata
- > nodes eval:[b'\x0a\x86\x32\x1f\x13\x79\xd1\xa9\xec\xd0\x57\x9a\x22\x97\x7a\xf7\xa5\xac\xaf\x11']
- > path eval:b'a'
- > fields eval:[b'revision']
- > haveparents eval:False
- > EOF
- creating http peer for wire protocol version 2
- sending filedata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 84
- ]
- ],
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- b'a0\n00000000000000000000000000000000000000\n11111111111111111111111111111111111111\na1\n'
- ]
-
-haveparents=True should emit a delta
-
- $ sendhttpv2peer << EOF
- > command filedata
- > nodes eval:[b'\x0a\x86\x32\x1f\x13\x79\xd1\xa9\xec\xd0\x57\x9a\x22\x97\x7a\xf7\xa5\xac\xaf\x11']
- > path eval:b'a'
- > fields eval:[b'revision']
- > haveparents eval:True
- > EOF
- creating http peer for wire protocol version 2
- sending filedata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'deltabasenode': b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9',
- b'fieldsfollowing': [
- [
- b'delta',
- 15
- ]
- ],
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- b'\x00\x00\x00Q\x00\x00\x00Q\x00\x00\x00\x03a1\n'
- ]
-
-Requesting multiple revisions works
-(first revision is a fulltext since haveparents=False by default)
-
- $ sendhttpv2peer << EOF
- > command filedata
- > nodes eval:[b'\x64\x9d\x14\x9d\xf4\x3d\x83\x88\x25\x23\xb7\xfb\x1e\x6a\x3a\xf6\xf1\x90\x7b\x39', b'\x0a\x86\x32\x1f\x13\x79\xd1\xa9\xec\xd0\x57\x9a\x22\x97\x7a\xf7\xa5\xac\xaf\x11']
- > path eval:b'a'
- > fields eval:[b'revision']
- > EOF
- creating http peer for wire protocol version 2
- sending filedata command
- response: gen[
- {
- b'totalitems': 2
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 81
- ]
- ],
- b'node': b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9'
- },
- b'a0\n00000000000000000000000000000000000000\n11111111111111111111111111111111111111\n',
- {
- b'deltabasenode': b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9',
- b'fieldsfollowing': [
- [
- b'delta',
- 15
- ]
- ],
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- b'\x00\x00\x00Q\x00\x00\x00Q\x00\x00\x00\x03a1\n'
- ]
-
-Revisions are sorted by DAG order, parents first
-
- $ sendhttpv2peer << EOF
- > command filedata
- > nodes eval:[b'\x0a\x86\x32\x1f\x13\x79\xd1\xa9\xec\xd0\x57\x9a\x22\x97\x7a\xf7\xa5\xac\xaf\x11', b'\x64\x9d\x14\x9d\xf4\x3d\x83\x88\x25\x23\xb7\xfb\x1e\x6a\x3a\xf6\xf1\x90\x7b\x39']
- > path eval:b'a'
- > fields eval:[b'revision']
- > EOF
- creating http peer for wire protocol version 2
- sending filedata command
- response: gen[
- {
- b'totalitems': 2
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 81
- ]
- ],
- b'node': b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9'
- },
- b'a0\n00000000000000000000000000000000000000\n11111111111111111111111111111111111111\n',
- {
- b'deltabasenode': b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9',
- b'fieldsfollowing': [
- [
- b'delta',
- 15
- ]
- ],
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- b'\x00\x00\x00Q\x00\x00\x00Q\x00\x00\x00\x03a1\n'
- ]
-
-Requesting parents and revision data works
-
- $ sendhttpv2peer << EOF
- > command filedata
- > nodes eval:[b'\x7e\x58\x01\xb6\xd5\xf0\x3a\x5a\x54\xf3\xc4\x7b\x58\x3f\x75\x67\xaa\xd4\x3e\x5b']
- > path eval:b'a'
- > fields eval:[b'parents', b'revision']
- > EOF
- creating http peer for wire protocol version 2
- sending filedata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 84
- ]
- ],
- b'node': b'~X\x01\xb6\xd5\xf0:ZT\xf3\xc4{X?ug\xaa\xd4>[',
- b'parents': [
- b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- },
- b'a0\n00000000000000000000000000000000000000\n11111111111111111111111111111111111111\na2\n'
- ]
-
-Linknode for duplicate revision is the initial revision
-
- $ sendhttpv2peer << EOF
- > command filedata
- > nodes eval:[b'\x2e\xd2\xa3\x91\x2a\x0b\x24\x50\x20\x43\xea\xe8\x4e\xe4\xb2\x79\xc1\x8b\x90\xdd']
- > path eval:b'dupe-file'
- > fields eval:[b'linknode', b'parents', b'revision']
- > EOF
- creating http peer for wire protocol version 2
- sending filedata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 4
- ]
- ],
- b'linknode': b'C4\xf1\x08\x97\xd1<>\x8b\xebKcorr\xb4\xec-\x03"',
- b'node': b'.\xd2\xa3\x91*\x0b$P C\xea\xe8N\xe4\xb2y\xc1\x8b\x90\xdd',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- },
- b'foo\n'
- ]
-
- $ cat error.log
--- a/tests/test-wireproto-command-filesdata.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1298 +0,0 @@
- $ . $TESTDIR/wireprotohelpers.sh
-
- $ hg init server
- $ enablehttpv2 server
- $ cd server
- $ cat > a << EOF
- > a0
- > 00000000000000000000000000000000000000
- > 11111111111111111111111111111111111111
- > EOF
- $ cat > b << EOF
- > b0
- > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- > bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
- > EOF
- $ mkdir -p dir0/child0 dir0/child1 dir1
- $ echo c0 > dir0/c
- $ echo d0 > dir0/d
- $ echo e0 > dir0/child0/e
- $ echo f0 > dir0/child1/f
- $ hg -q commit -A -m 'commit 0'
-
- $ echo a1 >> a
- $ echo d1 > dir0/d
- $ echo g0 > g
- $ echo h0 > h
- $ hg -q commit -A -m 'commit 1'
- $ echo f1 > dir0/child1/f
- $ echo i0 > dir0/i
- $ hg -q commit -A -m 'commit 2'
-
- $ hg -q up -r 0
- $ echo a2 >> a
- $ hg commit -m 'commit 3'
- created new head
-
-Create multiple heads introducing the same file nodefile node
-
- $ hg -q up -r 0
- $ echo foo > dupe-file
- $ hg commit -Am 'dupe 1'
- adding dupe-file
- created new head
- $ hg -q up -r 0
- $ echo foo > dupe-file
- $ hg commit -Am 'dupe 2'
- adding dupe-file
- created new head
-
- $ hg log -G -T '{rev}:{node} {desc}\n'
- @ 5:47fc30580911232cb264675b402819deddf6c6f0 dupe 2
- |
- | o 4:b16cce2967c1749ef4f4e3086a806cfbad8a3af7 dupe 1
- |/
- | o 3:476fbf122cd82f6726f0191ff146f67140946abc commit 3
- |/
- | o 2:b91c03cbba3519ab149b6cd0a0afbdb5cf1b5c8a commit 2
- | |
- | o 1:5b0b1a23577e205ea240e39c9704e28d7697cbd8 commit 1
- |/
- o 0:6e875ff18c227659ad6143bb3580c65700734884 commit 0
-
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-Missing arguments is an error
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- abort: missing required arguments: revisions
- [255]
-
-Bad pattern to pathfilter is rejected
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > ]}]
- > pathfilter eval:{b'include': [b'bad:foo']}
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- abort: include pattern must begin with `path:` or `rootfilesin:`; got bad:foo
- [255]
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > ]}]
- > pathfilter eval:{b'exclude': [b'glob:foo']}
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- abort: exclude pattern must begin with `path:` or `rootfilesin:`; got glob:foo
- [255]
-
-Fetching a single changeset without parents fetches all files
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > ]}]
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 8,
- b'totalpaths': 8
- },
- {
- b'path': b'a',
- b'totalitems': 1
- },
- {
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- {
- b'path': b'b',
- b'totalitems': 1
- },
- {
- b'node': b'\x88\xbac\xb8\xd8\xc6 :\xc6z\xc9\x98\xac\xd9\x17K\xf7\x05!\xb2'
- },
- {
- b'path': b'dir0/c',
- b'totalitems': 1
- },
- {
- b'node': b'\x91DE4j\x0c\xa0b\x9b\xd4|\xeb]\xfe\x07\xe4\xd4\xcf%\x01'
- },
- {
- b'path': b'dir0/child0/e',
- b'totalitems': 1
- },
- {
- b'node': b'\xbb\xbal\x06\xb3\x0fD=4\xff\x84\x1b\xc9\x85\xc4\xd0\x82|k\xe4'
- },
- {
- b'path': b'dir0/child1/f',
- b'totalitems': 1
- },
- {
- b'node': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4'
- },
- {
- b'path': b'dir0/d',
- b'totalitems': 1
- },
- {
- b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
- },
- {
- b'path': b'g',
- b'totalitems': 1
- },
- {
- b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
- },
- {
- b'path': b'h',
- b'totalitems': 1
- },
- {
- b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
- }
- ]
-
-Fetching a single changeset saying parents data is available fetches just new files
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > ]}]
- > haveparents eval:True
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 4,
- b'totalpaths': 4
- },
- {
- b'path': b'a',
- b'totalitems': 1
- },
- {
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- {
- b'path': b'dir0/d',
- b'totalitems': 1
- },
- {
- b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
- },
- {
- b'path': b'g',
- b'totalitems': 1
- },
- {
- b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
- },
- {
- b'path': b'h',
- b'totalitems': 1
- },
- {
- b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
- }
- ]
-
-A path filter for a sub-directory is honored
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > ]}]
- > haveparents eval:True
- > pathfilter eval:{b'include': [b'path:dir0']}
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 1,
- b'totalpaths': 1
- },
- {
- b'path': b'dir0/d',
- b'totalitems': 1
- },
- {
- b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
- }
- ]
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > ]}]
- > haveparents eval:True
- > pathfilter eval:{b'exclude': [b'path:a', b'path:g']}
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 2,
- b'totalpaths': 2
- },
- {
- b'path': b'dir0/d',
- b'totalitems': 1
- },
- {
- b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
- },
- {
- b'path': b'h',
- b'totalitems': 1
- },
- {
- b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
- }
- ]
-
-Requesting multiple changeset nodes without haveparents sends all data for both
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > b'\xb9\x1c\x03\xcb\xba\x35\x19\xab\x14\x9b\x6c\xd0\xa0\xaf\xbd\xb5\xcf\x1b\x5c\x8a',
- > ]}]
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 10,
- b'totalpaths': 9
- },
- {
- b'path': b'a',
- b'totalitems': 1
- },
- {
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- {
- b'path': b'b',
- b'totalitems': 1
- },
- {
- b'node': b'\x88\xbac\xb8\xd8\xc6 :\xc6z\xc9\x98\xac\xd9\x17K\xf7\x05!\xb2'
- },
- {
- b'path': b'dir0/c',
- b'totalitems': 1
- },
- {
- b'node': b'\x91DE4j\x0c\xa0b\x9b\xd4|\xeb]\xfe\x07\xe4\xd4\xcf%\x01'
- },
- {
- b'path': b'dir0/child0/e',
- b'totalitems': 1
- },
- {
- b'node': b'\xbb\xbal\x06\xb3\x0fD=4\xff\x84\x1b\xc9\x85\xc4\xd0\x82|k\xe4'
- },
- {
- b'path': b'dir0/child1/f',
- b'totalitems': 2
- },
- {
- b'node': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4'
- },
- {
- b'node': b'(\xc7v\xae\x08\xd0\xd5^\xb4\x06H\xb4\x01\xb9\x0f\xf5DH4\x8e'
- },
- {
- b'path': b'dir0/d',
- b'totalitems': 1
- },
- {
- b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
- },
- {
- b'path': b'dir0/i',
- b'totalitems': 1
- },
- {
- b'node': b'\xd7t\xb5\x80Jq\xfd1\xe1\xae\x05\xea\x8e2\xdd\x9b\xa3\xd8S\xd7'
- },
- {
- b'path': b'g',
- b'totalitems': 1
- },
- {
- b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
- },
- {
- b'path': b'h',
- b'totalitems': 1
- },
- {
- b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
- }
- ]
-
-Requesting multiple changeset nodes with haveparents sends incremental data for both
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > b'\xb9\x1c\x03\xcb\xba\x35\x19\xab\x14\x9b\x6c\xd0\xa0\xaf\xbd\xb5\xcf\x1b\x5c\x8a',
- > ]}]
- > haveparents eval:True
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 6,
- b'totalpaths': 6
- },
- {
- b'path': b'a',
- b'totalitems': 1
- },
- {
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- {
- b'path': b'dir0/child1/f',
- b'totalitems': 1
- },
- {
- b'node': b'(\xc7v\xae\x08\xd0\xd5^\xb4\x06H\xb4\x01\xb9\x0f\xf5DH4\x8e'
- },
- {
- b'path': b'dir0/d',
- b'totalitems': 1
- },
- {
- b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
- },
- {
- b'path': b'dir0/i',
- b'totalitems': 1
- },
- {
- b'node': b'\xd7t\xb5\x80Jq\xfd1\xe1\xae\x05\xea\x8e2\xdd\x9b\xa3\xd8S\xd7'
- },
- {
- b'path': b'g',
- b'totalitems': 1
- },
- {
- b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
- },
- {
- b'path': b'h',
- b'totalitems': 1
- },
- {
- b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
- }
- ]
-
-Requesting parents works
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > ]}]
- > fields eval:[b'parents']
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 8,
- b'totalpaths': 8
- },
- {
- b'path': b'a',
- b'totalitems': 1
- },
- {
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11',
- b'parents': [
- b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- },
- {
- b'path': b'b',
- b'totalitems': 1
- },
- {
- b'node': b'\x88\xbac\xb8\xd8\xc6 :\xc6z\xc9\x98\xac\xd9\x17K\xf7\x05!\xb2',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- },
- {
- b'path': b'dir0/c',
- b'totalitems': 1
- },
- {
- b'node': b'\x91DE4j\x0c\xa0b\x9b\xd4|\xeb]\xfe\x07\xe4\xd4\xcf%\x01',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- },
- {
- b'path': b'dir0/child0/e',
- b'totalitems': 1
- },
- {
- b'node': b'\xbb\xbal\x06\xb3\x0fD=4\xff\x84\x1b\xc9\x85\xc4\xd0\x82|k\xe4',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- },
- {
- b'path': b'dir0/child1/f',
- b'totalitems': 1
- },
- {
- b'node': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- },
- {
- b'path': b'dir0/d',
- b'totalitems': 1
- },
- {
- b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G',
- b'parents': [
- b'S\x82\x06\xdc\x97\x1eR\x15@\xd6\x84:\xbf\xe6\xd1`2\xf6\xd4&',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- },
- {
- b'path': b'g',
- b'totalitems': 1
- },
- {
- b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- },
- {
- b'path': b'h',
- b'totalitems': 1
- },
- {
- b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- }
- ]
-
-Requesting revision data works
-(haveparents defaults to False, so fulltext is emitted)
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > ]}]
- > fields eval:[b'revision']
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 8,
- b'totalpaths': 8
- },
- {
- b'path': b'a',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 84
- ]
- ],
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- b'a0\n00000000000000000000000000000000000000\n11111111111111111111111111111111111111\na1\n',
- {
- b'path': b'b',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 81
- ]
- ],
- b'node': b'\x88\xbac\xb8\xd8\xc6 :\xc6z\xc9\x98\xac\xd9\x17K\xf7\x05!\xb2'
- },
- b'b0\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n',
- {
- b'path': b'dir0/c',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\x91DE4j\x0c\xa0b\x9b\xd4|\xeb]\xfe\x07\xe4\xd4\xcf%\x01'
- },
- b'c0\n',
- {
- b'path': b'dir0/child0/e',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\xbb\xbal\x06\xb3\x0fD=4\xff\x84\x1b\xc9\x85\xc4\xd0\x82|k\xe4'
- },
- b'e0\n',
- {
- b'path': b'dir0/child1/f',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4'
- },
- b'f0\n',
- {
- b'path': b'dir0/d',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
- },
- b'd1\n',
- {
- b'path': b'g',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
- },
- b'g0\n',
- {
- b'path': b'h',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
- },
- b'h0\n'
- ]
-
-haveparents=False should be same as above
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > ]}]
- > fields eval:[b'revision']
- > haveparents eval:False
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 8,
- b'totalpaths': 8
- },
- {
- b'path': b'a',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 84
- ]
- ],
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- b'a0\n00000000000000000000000000000000000000\n11111111111111111111111111111111111111\na1\n',
- {
- b'path': b'b',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 81
- ]
- ],
- b'node': b'\x88\xbac\xb8\xd8\xc6 :\xc6z\xc9\x98\xac\xd9\x17K\xf7\x05!\xb2'
- },
- b'b0\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n',
- {
- b'path': b'dir0/c',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\x91DE4j\x0c\xa0b\x9b\xd4|\xeb]\xfe\x07\xe4\xd4\xcf%\x01'
- },
- b'c0\n',
- {
- b'path': b'dir0/child0/e',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\xbb\xbal\x06\xb3\x0fD=4\xff\x84\x1b\xc9\x85\xc4\xd0\x82|k\xe4'
- },
- b'e0\n',
- {
- b'path': b'dir0/child1/f',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4'
- },
- b'f0\n',
- {
- b'path': b'dir0/d',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
- },
- b'd1\n',
- {
- b'path': b'g',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
- },
- b'g0\n',
- {
- b'path': b'h',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
- },
- b'h0\n'
- ]
-
-haveparents=True should emit a delta
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > ]}]
- > fields eval:[b'revision']
- > haveparents eval:True
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 4,
- b'totalpaths': 4
- },
- {
- b'path': b'a',
- b'totalitems': 1
- },
- {
- b'deltabasenode': b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9',
- b'fieldsfollowing': [
- [
- b'delta',
- 15
- ]
- ],
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- b'\x00\x00\x00Q\x00\x00\x00Q\x00\x00\x00\x03a1\n',
- {
- b'path': b'dir0/d',
- b'totalitems': 1
- },
- {
- b'deltabasenode': b'S\x82\x06\xdc\x97\x1eR\x15@\xd6\x84:\xbf\xe6\xd1`2\xf6\xd4&',
- b'fieldsfollowing': [
- [
- b'delta',
- 15
- ]
- ],
- b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
- },
- b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03d1\n',
- {
- b'path': b'g',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
- },
- b'g0\n',
- {
- b'path': b'h',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
- },
- b'h0\n'
- ]
-
-Requesting multiple revisions works
-(first revision is a fulltext since haveparents=False by default)
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x6e\x87\x5f\xf1\x8c\x22\x76\x59\xad\x61\x43\xbb\x35\x80\xc6\x57\x00\x73\x48\x84',
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > b'\xb9\x1c\x03\xcb\xba\x35\x19\xab\x14\x9b\x6c\xd0\xa0\xaf\xbd\xb5\xcf\x1b\x5c\x8a',
- > ]}]
- > fields eval:[b'revision']
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 12,
- b'totalpaths': 9
- },
- {
- b'path': b'a',
- b'totalitems': 2
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 81
- ]
- ],
- b'node': b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9'
- },
- b'a0\n00000000000000000000000000000000000000\n11111111111111111111111111111111111111\n',
- {
- b'deltabasenode': b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9',
- b'fieldsfollowing': [
- [
- b'delta',
- 15
- ]
- ],
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- b'\x00\x00\x00Q\x00\x00\x00Q\x00\x00\x00\x03a1\n',
- {
- b'path': b'b',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 81
- ]
- ],
- b'node': b'\x88\xbac\xb8\xd8\xc6 :\xc6z\xc9\x98\xac\xd9\x17K\xf7\x05!\xb2'
- },
- b'b0\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n',
- {
- b'path': b'dir0/c',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\x91DE4j\x0c\xa0b\x9b\xd4|\xeb]\xfe\x07\xe4\xd4\xcf%\x01'
- },
- b'c0\n',
- {
- b'path': b'dir0/child0/e',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\xbb\xbal\x06\xb3\x0fD=4\xff\x84\x1b\xc9\x85\xc4\xd0\x82|k\xe4'
- },
- b'e0\n',
- {
- b'path': b'dir0/child1/f',
- b'totalitems': 2
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4'
- },
- b'f0\n',
- {
- b'deltabasenode': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4',
- b'fieldsfollowing': [
- [
- b'delta',
- 15
- ]
- ],
- b'node': b'(\xc7v\xae\x08\xd0\xd5^\xb4\x06H\xb4\x01\xb9\x0f\xf5DH4\x8e'
- },
- b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03f1\n',
- {
- b'path': b'dir0/d',
- b'totalitems': 2
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'S\x82\x06\xdc\x97\x1eR\x15@\xd6\x84:\xbf\xe6\xd1`2\xf6\xd4&'
- },
- b'd0\n',
- {
- b'deltabasenode': b'S\x82\x06\xdc\x97\x1eR\x15@\xd6\x84:\xbf\xe6\xd1`2\xf6\xd4&',
- b'fieldsfollowing': [
- [
- b'delta',
- 15
- ]
- ],
- b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
- },
- b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03d1\n',
- {
- b'path': b'dir0/i',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\xd7t\xb5\x80Jq\xfd1\xe1\xae\x05\xea\x8e2\xdd\x9b\xa3\xd8S\xd7'
- },
- b'i0\n',
- {
- b'path': b'g',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
- },
- b'g0\n',
- {
- b'path': b'h',
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 3
- ]
- ],
- b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
- },
- b'h0\n'
- ]
-
-Requesting linknode field works
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x6e\x87\x5f\xf1\x8c\x22\x76\x59\xad\x61\x43\xbb\x35\x80\xc6\x57\x00\x73\x48\x84',
- > b'\x5b\x0b\x1a\x23\x57\x7e\x20\x5e\xa2\x40\xe3\x9c\x97\x04\xe2\x8d\x76\x97\xcb\xd8',
- > b'\xb9\x1c\x03\xcb\xba\x35\x19\xab\x14\x9b\x6c\xd0\xa0\xaf\xbd\xb5\xcf\x1b\x5c\x8a',
- > ]}]
- > fields eval:[b'linknode']
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 12,
- b'totalpaths': 9
- },
- {
- b'path': b'a',
- b'totalitems': 2
- },
- {
- b'linknode': b'n\x87_\xf1\x8c"vY\xadaC\xbb5\x80\xc6W\x00sH\x84',
- b'node': b'd\x9d\x14\x9d\xf4=\x83\x88%#\xb7\xfb\x1ej:\xf6\xf1\x90{9'
- },
- {
- b'linknode': b'[\x0b\x1a#W~ ^\xa2@\xe3\x9c\x97\x04\xe2\x8dv\x97\xcb\xd8',
- b'node': b'\n\x862\x1f\x13y\xd1\xa9\xec\xd0W\x9a"\x97z\xf7\xa5\xac\xaf\x11'
- },
- {
- b'path': b'b',
- b'totalitems': 1
- },
- {
- b'linknode': b'n\x87_\xf1\x8c"vY\xadaC\xbb5\x80\xc6W\x00sH\x84',
- b'node': b'\x88\xbac\xb8\xd8\xc6 :\xc6z\xc9\x98\xac\xd9\x17K\xf7\x05!\xb2'
- },
- {
- b'path': b'dir0/c',
- b'totalitems': 1
- },
- {
- b'linknode': b'n\x87_\xf1\x8c"vY\xadaC\xbb5\x80\xc6W\x00sH\x84',
- b'node': b'\x91DE4j\x0c\xa0b\x9b\xd4|\xeb]\xfe\x07\xe4\xd4\xcf%\x01'
- },
- {
- b'path': b'dir0/child0/e',
- b'totalitems': 1
- },
- {
- b'linknode': b'n\x87_\xf1\x8c"vY\xadaC\xbb5\x80\xc6W\x00sH\x84',
- b'node': b'\xbb\xbal\x06\xb3\x0fD=4\xff\x84\x1b\xc9\x85\xc4\xd0\x82|k\xe4'
- },
- {
- b'path': b'dir0/child1/f',
- b'totalitems': 2
- },
- {
- b'linknode': b'n\x87_\xf1\x8c"vY\xadaC\xbb5\x80\xc6W\x00sH\x84',
- b'node': b'\x12\xfc}\xcdw;Z\n\x92\x9c\xe1\x95"\x80\x83\xc6\xdd\xc9\xce\xc4'
- },
- {
- b'linknode': b'\xb9\x1c\x03\xcb\xba5\x19\xab\x14\x9bl\xd0\xa0\xaf\xbd\xb5\xcf\x1b\\\x8a',
- b'node': b'(\xc7v\xae\x08\xd0\xd5^\xb4\x06H\xb4\x01\xb9\x0f\xf5DH4\x8e'
- },
- {
- b'path': b'dir0/d',
- b'totalitems': 2
- },
- {
- b'linknode': b'n\x87_\xf1\x8c"vY\xadaC\xbb5\x80\xc6W\x00sH\x84',
- b'node': b'S\x82\x06\xdc\x97\x1eR\x15@\xd6\x84:\xbf\xe6\xd1`2\xf6\xd4&'
- },
- {
- b'linknode': b'[\x0b\x1a#W~ ^\xa2@\xe3\x9c\x97\x04\xe2\x8dv\x97\xcb\xd8',
- b'node': b'\x93\x88)\xad\x01R}2\xba\x06_\x81#6\xfe\xc7\x9d\xdd9G'
- },
- {
- b'path': b'dir0/i',
- b'totalitems': 1
- },
- {
- b'linknode': b'\xb9\x1c\x03\xcb\xba5\x19\xab\x14\x9bl\xd0\xa0\xaf\xbd\xb5\xcf\x1b\\\x8a',
- b'node': b'\xd7t\xb5\x80Jq\xfd1\xe1\xae\x05\xea\x8e2\xdd\x9b\xa3\xd8S\xd7'
- },
- {
- b'path': b'g',
- b'totalitems': 1
- },
- {
- b'linknode': b'[\x0b\x1a#W~ ^\xa2@\xe3\x9c\x97\x04\xe2\x8dv\x97\xcb\xd8',
- b'node': b'\xde\xca\xba5DFjI\x95r\xe9\x0f\xac\xe6\xfa\x0c!k\xba\x8c'
- },
- {
- b'path': b'h',
- b'totalitems': 1
- },
- {
- b'linknode': b'[\x0b\x1a#W~ ^\xa2@\xe3\x9c\x97\x04\xe2\x8dv\x97\xcb\xd8',
- b'node': b'\x03A\xfc\x84\x1b\xb5\xb4\xba\x93\xb2mM\xdaa\xf7y6]\xb3K'
- }
- ]
-
-Test behavior where a file node is introduced in 2 DAG heads
-
-Request for changeset introducing filenode returns linknode as self
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\xb1\x6c\xce\x29\x67\xc1\x74\x9e\xf4\xf4\xe3\x08\x6a\x80\x6c\xfb\xad\x8a\x3a\xf7',
- > ]}]
- > fields eval:[b'linknode']
- > pathfilter eval:{b'include': [b'path:dupe-file']}
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 1,
- b'totalpaths': 1
- },
- {
- b'path': b'dupe-file',
- b'totalitems': 1
- },
- {
- b'linknode': b'\xb1l\xce)g\xc1t\x9e\xf4\xf4\xe3\x08j\x80l\xfb\xad\x8a:\xf7',
- b'node': b'.\xd2\xa3\x91*\x0b$P C\xea\xe8N\xe4\xb2y\xc1\x8b\x90\xdd'
- }
- ]
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\xb1\x6c\xce\x29\x67\xc1\x74\x9e\xf4\xf4\xe3\x08\x6a\x80\x6c\xfb\xad\x8a\x3a\xf7',
- > ]}]
- > fields eval:[b'linknode']
- > haveparents eval:True
- > pathfilter eval:{b'include': [b'path:dupe-file']}
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 1,
- b'totalpaths': 1
- },
- {
- b'path': b'dupe-file',
- b'totalitems': 1
- },
- {
- b'linknode': b'\xb1l\xce)g\xc1t\x9e\xf4\xf4\xe3\x08j\x80l\xfb\xad\x8a:\xf7',
- b'node': b'.\xd2\xa3\x91*\x0b$P C\xea\xe8N\xe4\xb2y\xc1\x8b\x90\xdd'
- }
- ]
-
-Request for changeset where recorded linknode isn't in DAG ancestry will get
-rewritten accordingly
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x47\xfc\x30\x58\x09\x11\x23\x2c\xb2\x64\x67\x5b\x40\x28\x19\xde\xdd\xf6\xc6\xf0',
- > ]}]
- > fields eval:[b'linknode']
- > pathfilter eval:{b'include': [b'path:dupe-file']}
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 1,
- b'totalpaths': 1
- },
- {
- b'path': b'dupe-file',
- b'totalitems': 1
- },
- {
- b'linknode': b'G\xfc0X\t\x11#,\xb2dg[@(\x19\xde\xdd\xf6\xc6\xf0',
- b'node': b'.\xd2\xa3\x91*\x0b$P C\xea\xe8N\xe4\xb2y\xc1\x8b\x90\xdd'
- }
- ]
-
- $ sendhttpv2peer << EOF
- > command filesdata
- > revisions eval:[{
- > b'type': b'changesetexplicit',
- > b'nodes': [
- > b'\x47\xfc\x30\x58\x09\x11\x23\x2c\xb2\x64\x67\x5b\x40\x28\x19\xde\xdd\xf6\xc6\xf0',
- > ]}]
- > fields eval:[b'linknode']
- > haveparents eval:True
- > pathfilter eval:{b'include': [b'path:dupe-file']}
- > EOF
- creating http peer for wire protocol version 2
- sending filesdata command
- response: gen[
- {
- b'totalitems': 1,
- b'totalpaths': 1
- },
- {
- b'path': b'dupe-file',
- b'totalitems': 1
- },
- {
- b'linknode': b'G\xfc0X\t\x11#,\xb2dg[@(\x19\xde\xdd\xf6\xc6\xf0',
- b'node': b'.\xd2\xa3\x91*\x0b$P C\xea\xe8N\xe4\xb2y\xc1\x8b\x90\xdd'
- }
- ]
-
- $ cat error.log
--- a/tests/test-wireproto-command-heads.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
- $ . $TESTDIR/wireprotohelpers.sh
-
- $ hg init server
- $ enablehttpv2 server
- $ cd server
- $ hg debugdrawdag << EOF
- > H I J
- > | | |
- > E F G
- > | |/
- > C D
- > |/
- > B
- > |
- > A
- > EOF
-
- $ hg phase --force --secret J
- $ hg phase --public E
-
- $ hg log -r 'E + H + I + G + J' -T '{rev}:{node} {desc} {phase}\n'
- 4:78d2dca436b2f5b188ac267e29b81e07266d38fc E public
- 7:ae492e36b0c8339ffaf328d00b85b4525de1165e H draft
- 8:1d6f6b91d44aaba6d5e580bc30a9948530dbe00b I draft
- 6:29446d2dc5419c5f97447a8bc062e4cc328bf241 G draft
- 9:dec04b246d7cbb670c6689806c05ad17c835284e J secret
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-All non-secret heads returned by default
-
- $ sendhttpv2peer << EOF
- > command heads
- > EOF
- creating http peer for wire protocol version 2
- sending heads command
- response: [
- b'\x1dok\x91\xd4J\xab\xa6\xd5\xe5\x80\xbc0\xa9\x94\x850\xdb\xe0\x0b',
- b'\xaeI.6\xb0\xc83\x9f\xfa\xf3(\xd0\x0b\x85\xb4R]\xe1\x16^',
- b')Dm-\xc5A\x9c_\x97Dz\x8b\xc0b\xe4\xcc2\x8b\xf2A'
- ]
-
-Requesting just the public heads works
-
- $ sendhttpv2peer << EOF
- > command heads
- > publiconly 1
- > EOF
- creating http peer for wire protocol version 2
- sending heads command
- response: [
- b'x\xd2\xdc\xa46\xb2\xf5\xb1\x88\xac&~)\xb8\x1e\x07&m8\xfc'
- ]
-
- $ cat error.log
--- a/tests/test-wireproto-command-known.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
- $ . $TESTDIR/wireprotohelpers.sh
-
- $ hg init server
- $ enablehttpv2 server
- $ cd server
- $ hg debugdrawdag << EOF
- > C D
- > |/
- > B
- > |
- > A
- > EOF
-
- $ hg log -T '{rev}:{node} {desc}\n'
- 3:be0ef73c17ade3fc89dc41701eb9fc3a91b58282 D
- 2:26805aba1e600a82e93661149f2313866a221a7b C
- 1:112478962961147124edd43549aedd1a335e44bf B
- 0:426bada5c67598ca65036d57d9e4b64b0c1ce7a0 A
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-No arguments returns something reasonable
-
- $ sendhttpv2peer << EOF
- > command known
- > EOF
- creating http peer for wire protocol version 2
- sending known command
- response: []
-
-Single known node works
-
- $ sendhttpv2peer << EOF
- > command known
- > nodes eval:[b'\x42\x6b\xad\xa5\xc6\x75\x98\xca\x65\x03\x6d\x57\xd9\xe4\xb6\x4b\x0c\x1c\xe7\xa0']
- > EOF
- creating http peer for wire protocol version 2
- sending known command
- response: [
- True
- ]
-
-Multiple nodes works
-
- $ sendhttpv2peer << EOF
- > command known
- > nodes eval:[b'\x42\x6b\xad\xa5\xc6\x75\x98\xca\x65\x03\x6d\x57\xd9\xe4\xb6\x4b\x0c\x1c\xe7\xa0', b'00000000000000000000', b'\x11\x24\x78\x96\x29\x61\x14\x71\x24\xed\xd4\x35\x49\xae\xdd\x1a\x33\x5e\x44\xbf']
- > EOF
- creating http peer for wire protocol version 2
- sending known command
- response: [
- True,
- False,
- True
- ]
-
- $ cat error.log
--- a/tests/test-wireproto-command-listkeys.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
- $ . $TESTDIR/wireprotohelpers.sh
-
- $ hg init server
- $ enablehttpv2 server
- $ cd server
- $ hg debugdrawdag << EOF
- > C D
- > |/
- > B
- > |
- > A
- > EOF
-
- $ hg phase --public -r C
- $ hg book -r C @
-
- $ hg log -T '{rev}:{node} {desc}\n'
- 3:be0ef73c17ade3fc89dc41701eb9fc3a91b58282 D
- 2:26805aba1e600a82e93661149f2313866a221a7b C
- 1:112478962961147124edd43549aedd1a335e44bf B
- 0:426bada5c67598ca65036d57d9e4b64b0c1ce7a0 A
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-Request for namespaces works
-
- $ sendhttpv2peer << EOF
- > command listkeys
- > namespace namespaces
- > EOF
- creating http peer for wire protocol version 2
- sending listkeys command
- response: {
- b'bookmarks': b'',
- b'namespaces': b'',
- b'phases': b''
- }
-
-Request for phases works
-
- $ sendhttpv2peer << EOF
- > command listkeys
- > namespace phases
- > EOF
- creating http peer for wire protocol version 2
- sending listkeys command
- response: {
- b'be0ef73c17ade3fc89dc41701eb9fc3a91b58282': b'1',
- b'publishing': b'True'
- }
-
-Request for bookmarks works
-
- $ sendhttpv2peer << EOF
- > command listkeys
- > namespace bookmarks
- > EOF
- creating http peer for wire protocol version 2
- sending listkeys command
- response: {
- b'@': b'26805aba1e600a82e93661149f2313866a221a7b'
- }
-
- $ cat error.log
--- a/tests/test-wireproto-command-lookup.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
- $ . $TESTDIR/wireprotohelpers.sh
-
- $ hg init server
- $ enablehttpv2 server
- $ cd server
- $ cat >> .hg/hgrc << EOF
- > [web]
- > push_ssl = false
- > allow-push = *
- > EOF
- $ hg debugdrawdag << EOF
- > C D
- > |/
- > B
- > |
- > A
- > EOF
- $ root_node=$(hg log -r A -T '{node}')
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-lookup for known node works
-
- $ sendhttpv2peer << EOF
- > command lookup
- > key $root_node
- > EOF
- creating http peer for wire protocol version 2
- sending lookup command
- response: b'Bk\xad\xa5\xc6u\x98\xcae\x03mW\xd9\xe4\xb6K\x0c\x1c\xe7\xa0'
-
- $ cat error.log
--- a/tests/test-wireproto-command-manifestdata.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,358 +0,0 @@
- $ . $TESTDIR/wireprotohelpers.sh
-
- $ hg init server
- $ enablehttpv2 server
- $ cd server
- $ echo a0 > a
- $ echo b0 > b
- $ mkdir -p dir0/child0 dir0/child1 dir1
- $ echo c0 > dir0/c
- $ echo d0 > dir0/d
- $ echo e0 > dir0/child0/e
- $ echo f0 > dir0/child1/f
- $ hg -q commit -A -m 'commit 0'
-
- $ echo a1 > a
- $ echo d1 > dir0/d
- $ hg commit -m 'commit 1'
- $ echo f0 > dir0/child1/f
- $ hg commit -m 'commit 2'
- nothing changed
- [1]
-
- $ hg -q up -r 0
- $ echo a2 > a
- $ hg commit -m 'commit 3'
- created new head
-
- $ hg log -G -T '{rev}:{node} {desc}\n'
- @ 2:c8757a2ffe552850d1e0dfe60d295ebf64c196d9 commit 3
- |
- | o 1:650165e803375748a94df471e5b58d85763e0b29 commit 1
- |/
- o 0:6d85ca1270b377d320098556ba5bfad34a9ee12d commit 0
-
-
- $ hg --debug debugindex -m
- rev linkrev nodeid p1 p2
- 0 0 1b175b595f022cfab5b809cc0ed551bd0b3ff5e4 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
- 1 1 91e0bdbfb0dde0023fa063edc1445f207a22eac7 1b175b595f022cfab5b809cc0ed551bd0b3ff5e4 0000000000000000000000000000000000000000
- 2 2 46a6721b5edaf0ea04b79a5cb3218854a4d2aba0 1b175b595f022cfab5b809cc0ed551bd0b3ff5e4 0000000000000000000000000000000000000000
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-Missing arguments is an error
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- abort: missing required arguments: nodes, tree
- [255]
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[]
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- abort: missing required arguments: tree
- [255]
-
-Unknown node is an error
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa']
- > tree eval:b''
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- abort: unknown node: \xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa (esc)
- [255]
-
-Fetching a single revision returns just metadata by default
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
- > tree eval:b''
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
- }
- ]
-
-Requesting parents works
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
- > tree eval:b''
- > fields eval:[b'parents']
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
- b'parents': [
- b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- }
- ]
-
-Requesting revision data works
-(haveparents defaults to false, so fulltext is emitted)
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
- > tree eval:b''
- > fields eval:[b'revision']
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 292
- ]
- ],
- b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
- },
- b'a\x000879345e39377229634b420c639454156726c6b6\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n'
- ]
-
-haveparents=False yields same output
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
- > tree eval:b''
- > fields eval:[b'revision']
- > haveparents eval:False
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 292
- ]
- ],
- b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
- },
- b'a\x000879345e39377229634b420c639454156726c6b6\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n'
- ]
-
-haveparents=True will emit delta
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
- > tree eval:b''
- > fields eval:[b'revision']
- > haveparents eval:True
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
- b'fieldsfollowing': [
- [
- b'delta',
- 55
- ]
- ],
- b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
- },
- b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
- ]
-
-Requesting multiple revisions works
-(haveparents defaults to false, so fulltext is emitted unless a parent
-has been emitted)
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4', b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
- > tree eval:b''
- > fields eval:[b'revision']
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 2
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 292
- ]
- ],
- b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4'
- },
- b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
- {
- b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
- b'fieldsfollowing': [
- [
- b'delta',
- 55
- ]
- ],
- b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
- },
- b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
- ]
-
-With haveparents=True, first revision is a delta instead of fulltext
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4', b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
- > tree eval:b''
- > fields eval:[b'revision']
- > haveparents eval:True
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 2
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 292
- ]
- ],
- b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4'
- },
- b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
- {
- b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
- b'fieldsfollowing': [
- [
- b'delta',
- 55
- ]
- ],
- b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
- },
- b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
- ]
-
-Revisions are sorted by DAG order, parents first
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0', b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4']
- > tree eval:b''
- > fields eval:[b'revision']
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 2
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 292
- ]
- ],
- b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4'
- },
- b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
- {
- b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
- b'fieldsfollowing': [
- [
- b'delta',
- 55
- ]
- ],
- b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0'
- },
- b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
- ]
-
-Requesting parents and revision data works
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x1b\x17\x5b\x59\x5f\x02\x2c\xfa\xb5\xb8\x09\xcc\x0e\xd5\x51\xbd\x0b\x3f\xf5\xe4', b'\x46\xa6\x72\x1b\x5e\xda\xf0\xea\x04\xb7\x9a\x5c\xb3\x21\x88\x54\xa4\xd2\xab\xa0']
- > tree eval:b''
- > fields eval:[b'parents', b'revision']
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 2
- },
- {
- b'fieldsfollowing': [
- [
- b'revision',
- 292
- ]
- ],
- b'node': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- },
- b'a\x002b4eb07319bfa077a40a2f04913659aef0da42da\nb\x00819e258d31a5e1606629f365bb902a1b21ee4216\ndir0/c\x00914445346a0ca0629bd47ceb5dfe07e4d4cf2501\ndir0/child0/e\x00bbba6c06b30f443d34ff841bc985c4d0827c6be4\ndir0/child1/f\x0012fc7dcd773b5a0a929ce195228083c6ddc9cec4\ndir0/d\x00538206dc971e521540d6843abfe6d16032f6d426\n',
- {
- b'deltabasenode': b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
- b'fieldsfollowing': [
- [
- b'delta',
- 55
- ]
- ],
- b'node': b'F\xa6r\x1b^\xda\xf0\xea\x04\xb7\x9a\\\xb3!\x88T\xa4\xd2\xab\xa0',
- b'parents': [
- b'\x1b\x17[Y_\x02,\xfa\xb5\xb8\t\xcc\x0e\xd5Q\xbd\x0b?\xf5\xe4',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- },
- b'\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x000879345e39377229634b420c639454156726c6b6\n'
- ]
-
- $ cat error.log
--- a/tests/test-wireproto-command-pushkey.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
- $ . $TESTDIR/wireprotohelpers.sh
-
- $ hg init server
- $ enablehttpv2 server
- $ cd server
- $ cat >> .hg/hgrc << EOF
- > [web]
- > push_ssl = false
- > allow-push = *
- > EOF
- $ hg debugdrawdag << EOF
- > C D
- > |/
- > B
- > |
- > A
- > EOF
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-pushkey for a bookmark works
-
- $ sendhttpv2peer << EOF
- > command pushkey
- > namespace bookmarks
- > key @
- > old
- > new 426bada5c67598ca65036d57d9e4b64b0c1ce7a0
- > EOF
- creating http peer for wire protocol version 2
- sending pushkey command
- response: True
-
- $ sendhttpv2peer << EOF
- > command listkeys
- > namespace bookmarks
- > EOF
- creating http peer for wire protocol version 2
- sending listkeys command
- response: {
- b'@': b'426bada5c67598ca65036d57d9e4b64b0c1ce7a0'
- }
-
- $ cat error.log
--- a/tests/test-wireproto-command-rawstorefiledata.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
- $ . $TESTDIR/wireprotohelpers.sh
- $ hg init server
- $ enablehttpv2 server
- $ cd server
- $ echo a0 > a
- $ echo b0 > b
- $ hg -q commit -A -m 'commit 0'
- $ echo a1 > a
- $ hg commit -m 'commit 1'
- $ mkdir dir0
- $ mkdir dir1
- $ echo c0 > dir0/c
- $ echo d0 > dir0/d
- $ echo e0 > dir1/e
- $ echo f0 > dir1/f
- $ hg commit -A -m 'commit 2'
- adding dir0/c
- adding dir0/d
- adding dir1/e
- adding dir1/f
- $ echo f1 > dir1/f
- $ hg commit -m 'commit 3'
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
-Missing requirement argument results in error
-
- $ sendhttpv2peer << EOF
- > command rawstorefiledata
- > EOF
- creating http peer for wire protocol version 2
- sending rawstorefiledata command
- abort: missing required arguments: files
- [255]
-
-Unknown files value results in error
-
- $ sendhttpv2peer << EOF
- > command rawstorefiledata
- > files eval:[b'unknown']
- > EOF
- creating http peer for wire protocol version 2
- sending rawstorefiledata command
- abort: unknown file type: unknown
- [255]
-
-Requesting just changelog works
-
- $ sendhttpv2peer << EOF
- > command rawstorefiledata
- > files eval:[b'changelog']
- > EOF
- creating http peer for wire protocol version 2
- sending rawstorefiledata command
- response: gen[
- {
- b'filecount': 1,
- b'totalsize': 527 (no-zstd !)
- b'totalsize': 530 (zstd !)
- },
- {
- b'location': b'store',
- b'path': b'00changelog.i',
- b'size': 527 (no-zstd !)
- b'size': 530 (zstd !)
- },
- b'\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00?\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u992f4779029a3df8d0666d00bb924f69634e2641\ntest\n0 0\na\nb\n\ncommit 0\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00>\x00\x00\x00=\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\xff\xff\xff\xffD2\xd86&\xe8\xa9\x86U\xf0b\xec\x1f*C\xb0\x7f\x7f\xbb\xb0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ua988fb43583e871d1ed5750ee074c6d840bbbfc8\ntest\n0 0\na\n\ncommit 1\x00\x00\x00\x00\x00~\x00\x00\x00\x00\x00N\x00\x00\x00W\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\xa4r\xd2\xea\x96U\x1a\x1e\xbb\x011-\xb2\xe6\xa7\x86\xd0F\x96o\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x9c%\xc5\xc1\t\xc0 \x0c\x05\xd0{\xa6p\x03cjI\xd71\xf9\x11<H\xa1u\x7fJ\xf1]\x9eyu\x98\xa2\xb0Z\x88jk0\x11\x95z\xa0\xdb\x11\\\x81S\xfc*\xb4\xe2]\xc4\x89\t\xe3\xe1\xec;\xfc\x95\x1c\xbbN\xe4\xf7\x9cc%\xf9\x00S#\x19\x13\x00\x00\x00\x00\x00\xcc\x00\x00\x00\x00\x00C\x00\x00\x00B\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x02\xff\xff\xff\xff\x85kg{\x94a\x12i\xc5lW5[\x85\xf9\x95|\xfc\xc1\xb9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u90231ddca36fa178a0eed99bd03078112487dda3\ntest\n0 0\ndir1/f\n\ncommit 3', (no-zstd !)
- b'\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00?\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u992f4779029a3df8d0666d00bb924f69634e2641\ntest\n0 0\na\nb\n\ncommit 0\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00>\x00\x00\x00=\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\xff\xff\xff\xffD2\xd86&\xe8\xa9\x86U\xf0b\xec\x1f*C\xb0\x7f\x7f\xbb\xb0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ua988fb43583e871d1ed5750ee074c6d840bbbfc8\ntest\n0 0\na\n\ncommit 1\x00\x00\x00\x00\x00~\x00\x00\x00\x00\x00Q\x00\x00\x00W\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\xa4r\xd2\xea\x96U\x1a\x1e\xbb\x011-\xb2\xe6\xa7\x86\xd0F\x96o\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\xb5/\xfd WE\x02\x00r\x04\x0f\x14\x90\x01\x0e#\xf7h$;NQC%\xf8f\xd7\xb1\x81\x8d+\x01\x16+)5\xa8\x19\xdaA\xae\xe3\x00\xe9v\xe2l\x05v\x19\x11\xd4\xc1onK\xa2\x17c\xb4\xf3\xe7 z\x13\x8f\x1c\xf3j4\x03\x03\x00`\x06\x84\x8b\x1a\n\x14\x00\x00\x00\x00\x00\xcf\x00\x00\x00\x00\x00C\x00\x00\x00B\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x02\xff\xff\xff\xff\x85kg{\x94a\x12i\xc5lW5[\x85\xf9\x95|\xfc\xc1\xb9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u90231ddca36fa178a0eed99bd03078112487dda3\ntest\n0 0\ndir1/f\n\ncommit 3', (zstd !)
- b''
- ]
-
-Requesting just manifestlog works (as impractical as that operation may be).
-
- $ sendhttpv2peer << EOF
- > command rawstorefiledata
- > files eval:[b'manifestlog']
- > EOF
- creating http peer for wire protocol version 2
- sending rawstorefiledata command
- response: gen[
- {
- b'filecount': 1,
- b'totalsize': 584 (no-zstd !)
- b'totalsize': 588 (zstd !)
- },
- {
- b'location': b'store',
- b'path': b'00manifest.i',
- b'size': 584 (no-zstd !)
- b'size': 588 (zstd !)
- },
- b'\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00\x00I\x00\x00\x00V\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x9c\r\xca\xc1\x11\x00!\x08\x040\xdfV\x03+\xa2\x94\xb3\x8c\xd0\x7f\twy\x87\x03i\x95r\x96F6\xe5\x1c\x9a\x10-\x16\xba|\x07\xab\xe5\xd1\xf08s\\\x8d\xc2\xbeo)w\xa9\x8b;\xa2\xff\x95\x19\x02jB\xab\x0c\xea\xf3\x03\xcf\x1d\x16\t\x00\x00\x00\x00\x00I\x00\x00\x00\x00\x007\x00\x00\x00V\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\xff\xff\xff\xff\xa9\x88\xfbCX>\x87\x1d\x1e\xd5u\x0e\xe0t\xc6\xd8@\xbb\xbf\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x009a38122997b3ac97be2a9aa2e556838341fdf2cc\n\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x8c\x00\x00\x01\x16\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\xbcL\xdb}\x10{\xe2w\xaa\xdb"rC\xdf\xb3\xe0M\xd5,\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x9c%\xcd\xb9\rB1\x10\x00Q\xc7\xbf\x19\xf6\xb6\xdd\x08\xb9\xf7\x92H\xa9\x90\xd2\xb8\x82\xc9\x9e4c\x8c\xfb\xf8\xf7\xca\xc7\x13n16\x8a\x88\xb2\xd8\x818`\xb4=eF\xb9f\x17\xcc\x92\x94hR\xc0\xeb\xe7s(/\x02\xcb\xd8\x13K\tU m\t\x1f\xef\xb2D\x03\xa6\xb6\x14\xb2\xaf\xc7[\rw?\x16`\xce\xd0"\x9c,\xddK\xd0c/\rIX4\xc3\xbc\xe4\xef{ u\xcc\x8c\x9c\x93]\x0f\x9cM;\n\xb7\x12-X\x1c\x96\x9fuT\xc8\xf5\x06\x88\xa25W\x00\x00\x00\x00\x01\x0c\x00\x00\x00\x00\x00<\x00\x00\x01\x16\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\xff\xff\xff\xff\x90#\x1d\xdc\xa3o\xa1x\xa0\xee\xd9\x9b\xd00x\x11$\x87\xdd\xa3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\x00\x00\x01\x16\x00\x00\x000dir1/f\x0028c776ae08d0d55eb40648b401b90ff54448348e\n', (no-zstd !)
- b'\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00\x00H\x00\x00\x00V\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\xb5/\xfd V\xfd\x01\x00b\xc5\x0e\x0f\xc0\xd1\x00\xfb\x0c\xb9\xca\xdf\xb2R\xba!\xf2\xf6\x1d\x80\xd5\x95Yc\xef9DaT\xcefcM\xf1\x12\t\x84\xf3\x1a\x04\x04N\\\'S\xf2\'\x8cz5\xc5\x9f\xfa\x18\xf3\x82W\x1a\x83Y\xe8\xf0\x00\x00\x00\x00\x00\x00H\x00\x00\x00\x00\x007\x00\x00\x00V\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\xff\xff\xff\xff\xa9\x88\xfbCX>\x87\x1d\x1e\xd5u\x0e\xe0t\xc6\xd8@\xbb\xbf\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x009a38122997b3ac97be2a9aa2e556838341fdf2cc\n\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x91\x00\x00\x01\x16\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\xbcL\xdb}\x10{\xe2w\xaa\xdb"rC\xdf\xb3\xe0M\xd5,\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\xb5/\xfd \xccE\x04\x00bK\x1e\x17\xb0A0\xff\xff\x9b\xb5V\x99\x99\xfa\xb6\xae\xf5n),"\xf1\n\x02\xb5\x07\x82++\xd1]T\x1b3\xaa\x8e\x10+)R\xa6\\\x9a\x10\xab+\xb4\x8bB\x9f\x13U\xd4\x98\xbd\xde \x9a\xf4\xd1}[\xfb{,q\x14Kf\x06\x1e\x10\xd6\x17\xbbl\x90\x16\xb9\xb3\xd8\x07\xee\xfc\xa8\x8eI\x10]\x9c\x1ava\x054W\xad\xdf\xb3\x18\xee\xbdd\x15\xdf$\x85St\n\xde\xee?\x91\xa0\x83\x11\x08\xd8\x01\x80\x10B\x04\x00\x04S\x04B\xc7Tw\x9f\xb9,\x00\x00\x00\x00\x01\x10\x00\x00\x00\x00\x00<\x00\x00\x01\x16\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\xff\xff\xff\xff\x90#\x1d\xdc\xa3o\xa1x\xa0\xee\xd9\x9b\xd00x\x11$\x87\xdd\xa3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\x00\x00\x01\x16\x00\x00\x000dir1/f\x0028c776ae08d0d55eb40648b401b90ff54448348e\n', (zstd !)
- b''
- ]
-
-Requesting both changelog and manifestlog works.
-
- $ sendhttpv2peer << EOF
- > command rawstorefiledata
- > files eval:[b'changelog', b'manifestlog']
- > EOF
- creating http peer for wire protocol version 2
- sending rawstorefiledata command
- response: gen[
- {
- b'filecount': 2,
- b'totalsize': 1111 (no-zstd !)
- b'totalsize': 1118 (zstd !)
- },
- {
- b'location': b'store',
- b'path': b'00manifest.i',
- b'size': 584 (no-zstd !)
- b'size': 588 (zstd !)
- },
- b'\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00\x00I\x00\x00\x00V\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x9c\r\xca\xc1\x11\x00!\x08\x040\xdfV\x03+\xa2\x94\xb3\x8c\xd0\x7f\twy\x87\x03i\x95r\x96F6\xe5\x1c\x9a\x10-\x16\xba|\x07\xab\xe5\xd1\xf08s\\\x8d\xc2\xbeo)w\xa9\x8b;\xa2\xff\x95\x19\x02jB\xab\x0c\xea\xf3\x03\xcf\x1d\x16\t\x00\x00\x00\x00\x00I\x00\x00\x00\x00\x007\x00\x00\x00V\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\xff\xff\xff\xff\xa9\x88\xfbCX>\x87\x1d\x1e\xd5u\x0e\xe0t\xc6\xd8@\xbb\xbf\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x009a38122997b3ac97be2a9aa2e556838341fdf2cc\n\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x8c\x00\x00\x01\x16\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\xbcL\xdb}\x10{\xe2w\xaa\xdb"rC\xdf\xb3\xe0M\xd5,\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x9c%\xcd\xb9\rB1\x10\x00Q\xc7\xbf\x19\xf6\xb6\xdd\x08\xb9\xf7\x92H\xa9\x90\xd2\xb8\x82\xc9\x9e4c\x8c\xfb\xf8\xf7\xca\xc7\x13n16\x8a\x88\xb2\xd8\x818`\xb4=eF\xb9f\x17\xcc\x92\x94hR\xc0\xeb\xe7s(/\x02\xcb\xd8\x13K\tU m\t\x1f\xef\xb2D\x03\xa6\xb6\x14\xb2\xaf\xc7[\rw?\x16`\xce\xd0"\x9c,\xddK\xd0c/\rIX4\xc3\xbc\xe4\xef{ u\xcc\x8c\x9c\x93]\x0f\x9cM;\n\xb7\x12-X\x1c\x96\x9fuT\xc8\xf5\x06\x88\xa25W\x00\x00\x00\x00\x01\x0c\x00\x00\x00\x00\x00<\x00\x00\x01\x16\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\xff\xff\xff\xff\x90#\x1d\xdc\xa3o\xa1x\xa0\xee\xd9\x9b\xd00x\x11$\x87\xdd\xa3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\x00\x00\x01\x16\x00\x00\x000dir1/f\x0028c776ae08d0d55eb40648b401b90ff54448348e\n', (no-zstd !)
- b'\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00\x00H\x00\x00\x00V\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\xb5/\xfd V\xfd\x01\x00b\xc5\x0e\x0f\xc0\xd1\x00\xfb\x0c\xb9\xca\xdf\xb2R\xba!\xf2\xf6\x1d\x80\xd5\x95Yc\xef9DaT\xcefcM\xf1\x12\t\x84\xf3\x1a\x04\x04N\\\'S\xf2\'\x8cz5\xc5\x9f\xfa\x18\xf3\x82W\x1a\x83Y\xe8\xf0\x00\x00\x00\x00\x00\x00H\x00\x00\x00\x00\x007\x00\x00\x00V\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\xff\xff\xff\xff\xa9\x88\xfbCX>\x87\x1d\x1e\xd5u\x0e\xe0t\xc6\xd8@\xbb\xbf\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00+a\x009a38122997b3ac97be2a9aa2e556838341fdf2cc\n\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x91\x00\x00\x01\x16\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\xbcL\xdb}\x10{\xe2w\xaa\xdb"rC\xdf\xb3\xe0M\xd5,\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\xb5/\xfd \xccE\x04\x00bK\x1e\x17\xb0A0\xff\xff\x9b\xb5V\x99\x99\xfa\xb6\xae\xf5n),"\xf1\n\x02\xb5\x07\x82++\xd1]T\x1b3\xaa\x8e\x10+)R\xa6\\\x9a\x10\xab+\xb4\x8bB\x9f\x13U\xd4\x98\xbd\xde \x9a\xf4\xd1}[\xfb{,q\x14Kf\x06\x1e\x10\xd6\x17\xbbl\x90\x16\xb9\xb3\xd8\x07\xee\xfc\xa8\x8eI\x10]\x9c\x1ava\x054W\xad\xdf\xb3\x18\xee\xbdd\x15\xdf$\x85St\n\xde\xee?\x91\xa0\x83\x11\x08\xd8\x01\x80\x10B\x04\x00\x04S\x04B\xc7Tw\x9f\xb9,\x00\x00\x00\x00\x01\x10\x00\x00\x00\x00\x00<\x00\x00\x01\x16\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\xff\xff\xff\xff\x90#\x1d\xdc\xa3o\xa1x\xa0\xee\xd9\x9b\xd00x\x11$\x87\xdd\xa3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\x00\x00\x01\x16\x00\x00\x000dir1/f\x0028c776ae08d0d55eb40648b401b90ff54448348e\n', (zstd !)
- b'',
- {
- b'location': b'store',
- b'path': b'00changelog.i',
- b'size': 527 (no-zstd !)
- b'size': 530 (zstd !)
- },
- b'\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00?\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u992f4779029a3df8d0666d00bb924f69634e2641\ntest\n0 0\na\nb\n\ncommit 0\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00>\x00\x00\x00=\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\xff\xff\xff\xffD2\xd86&\xe8\xa9\x86U\xf0b\xec\x1f*C\xb0\x7f\x7f\xbb\xb0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ua988fb43583e871d1ed5750ee074c6d840bbbfc8\ntest\n0 0\na\n\ncommit 1\x00\x00\x00\x00\x00~\x00\x00\x00\x00\x00N\x00\x00\x00W\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\xa4r\xd2\xea\x96U\x1a\x1e\xbb\x011-\xb2\xe6\xa7\x86\xd0F\x96o\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x9c%\xc5\xc1\t\xc0 \x0c\x05\xd0{\xa6p\x03cjI\xd71\xf9\x11<H\xa1u\x7fJ\xf1]\x9eyu\x98\xa2\xb0Z\x88jk0\x11\x95z\xa0\xdb\x11\\\x81S\xfc*\xb4\xe2]\xc4\x89\t\xe3\xe1\xec;\xfc\x95\x1c\xbbN\xe4\xf7\x9cc%\xf9\x00S#\x19\x13\x00\x00\x00\x00\x00\xcc\x00\x00\x00\x00\x00C\x00\x00\x00B\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x02\xff\xff\xff\xff\x85kg{\x94a\x12i\xc5lW5[\x85\xf9\x95|\xfc\xc1\xb9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u90231ddca36fa178a0eed99bd03078112487dda3\ntest\n0 0\ndir1/f\n\ncommit 3', (no-zstd !)
- b'\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00?\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u992f4779029a3df8d0666d00bb924f69634e2641\ntest\n0 0\na\nb\n\ncommit 0\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00>\x00\x00\x00=\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\xff\xff\xff\xffD2\xd86&\xe8\xa9\x86U\xf0b\xec\x1f*C\xb0\x7f\x7f\xbb\xb0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ua988fb43583e871d1ed5750ee074c6d840bbbfc8\ntest\n0 0\na\n\ncommit 1\x00\x00\x00\x00\x00~\x00\x00\x00\x00\x00Q\x00\x00\x00W\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\xa4r\xd2\xea\x96U\x1a\x1e\xbb\x011-\xb2\xe6\xa7\x86\xd0F\x96o\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\xb5/\xfd WE\x02\x00r\x04\x0f\x14\x90\x01\x0e#\xf7h$;NQC%\xf8f\xd7\xb1\x81\x8d+\x01\x16+)5\xa8\x19\xdaA\xae\xe3\x00\xe9v\xe2l\x05v\x19\x11\xd4\xc1onK\xa2\x17c\xb4\xf3\xe7 z\x13\x8f\x1c\xf3j4\x03\x03\x00`\x06\x84\x8b\x1a\n\x14\x00\x00\x00\x00\x00\xcf\x00\x00\x00\x00\x00C\x00\x00\x00B\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x02\xff\xff\xff\xff\x85kg{\x94a\x12i\xc5lW5[\x85\xf9\x95|\xfc\xc1\xb9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u90231ddca36fa178a0eed99bd03078112487dda3\ntest\n0 0\ndir1/f\n\ncommit 3', (zstd !)
- b''
- ]
-
- $ cat error.log
--- a/tests/test-wireproto-content-redirects.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1475 +0,0 @@
- $ . $TESTDIR/wireprotohelpers.sh
-
-persistent-nodemap is not enabled by default. It is not relevant for this test so disable it.
-
- $ cat >> $HGRCPATH << EOF
- > [format]
- > use-persistent-nodemap = no
- > [extensions]
- > blackbox =
- > [blackbox]
- > track = simplecache
- > EOF
-
- $ hg init server
- $ enablehttpv2 server
- $ cd server
- $ cat >> .hg/hgrc << EOF
- > [server]
- > compressionengines = zlib
- > [extensions]
- > simplecache = $TESTDIR/wireprotosimplecache.py
- > [simplecache]
- > cacheapi = true
- > EOF
-
- $ echo a0 > a
- $ echo b0 > b
- $ hg -q commit -A -m 'commit 0'
- $ echo a1 > a
- $ hg commit -m 'commit 1'
-
- $ hg --debug debugindex -m
- rev linkrev nodeid p1 p2
- 0 0 992f4779029a3df8d0666d00bb924f69634e2641 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
- 1 1 a988fb43583e871d1ed5750ee074c6d840bbbfc8 992f4779029a3df8d0666d00bb924f69634e2641 0000000000000000000000000000000000000000
-
- $ hg --config simplecache.redirectsfile=redirects.py serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
- $ cat > redirects.py << EOF
- > [
- > {
- > b'name': b'target-a',
- > b'protocol': b'http',
- > b'snirequired': False,
- > b'tlsversions': [b'1.2', b'1.3'],
- > b'uris': [b'http://example.com/'],
- > },
- > ]
- > EOF
-
-Redirect targets advertised when configured
-
- $ sendhttpv2peerhandshake << EOF
- > command capabilities
- > EOF
- creating http peer for wire protocol version 2
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
- s> x-hgproto-1: cbor\r\n
- s> x-hgupgrade-1: exp-http-v2-0003\r\n
- s> accept: application/mercurial-0.1\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-cbor\r\n
- s> Content-Length: 2289\r\n
- s> \r\n
- s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0003\xa5Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1LsparserevlogHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81\xa5DnameHtarget-aHprotocolDhttpKsnirequired\xf4Ktlsversions\x82C1.2C1.3Duris\x81Shttp://example.com/Nv1capabilitiesY\x01\xe4batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- (remote redirect target target-a is compatible) (tls1.2 !)
- (remote redirect target target-a requires unsupported TLS versions: 1.2, 1.3) (no-tls1.2 !)
- sending capabilities command
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> content-length: 111\r\n (tls1.2 !)
- s> content-length: 102\r\n (no-tls1.2 !)
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> \x1c\x00\x00\x01\x00\x01\x01\x82\xa1Pcontentencodings\x81HidentityC\x00\x00\x01\x00\x01\x00\x11\xa2DnameLcapabilitiesHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81Htarget-a (tls1.2 !)
- s> \x1c\x00\x00\x01\x00\x01\x01\x82\xa1Pcontentencodings\x81Hidentity:\x00\x00\x01\x00\x01\x00\x11\xa2DnameLcapabilitiesHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x80 (no-tls1.2 !)
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x01\x00\x02\x01\x92
- s> Hidentity
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x01\x00\x02\x041
- s> \xa1FstatusBok
- s> \r\n
- s> 6de\r\n
- s> \xd6\x06\x00\x01\x00\x02\x041
- s> \xa5Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1LsparserevlogHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81\xa5DnameHtarget-aHprotocolDhttpKsnirequired\xf4Ktlsversions\x82C1.2C1.3Duris\x81Shttp://example.com/
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x01\x00\x02\x002
- s> \r\n
- s> 0\r\n
- s> \r\n
- response: gen[
- {
- b'commands': {
- b'branchmap': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'capabilities': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'changesetdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'bookmarks',
- b'parents',
- b'phase',
- b'revision'
- ])
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filedata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'path': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filesdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'firstchangeset',
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'dict'
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 50000
- },
- b'heads': {
- b'args': {
- b'publiconly': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'known': {
- b'args': {
- b'nodes': {
- b'default': [],
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'listkeys': {
- b'args': {
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'lookup': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'manifestdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'tree': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 100000
- },
- b'pushkey': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- },
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- },
- b'new': {
- b'required': True,
- b'type': b'bytes'
- },
- b'old': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'push'
- ]
- },
- b'rawstorefiledata': {
- b'args': {
- b'files': {
- b'required': True,
- b'type': b'list'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- }
- },
- b'framingmediatypes': [
- b'application/mercurial-exp-framing-0006'
- ],
- b'pathfilterprefixes': set([
- b'path:',
- b'rootfilesin:'
- ]),
- b'rawrepoformats': [
- b'generaldelta',
- b'revlogv1',
- b'sparserevlog'
- ],
- b'redirect': {
- b'hashes': [
- b'sha256',
- b'sha1'
- ],
- b'targets': [
- {
- b'name': b'target-a',
- b'protocol': b'http',
- b'snirequired': False,
- b'tlsversions': [
- b'1.2',
- b'1.3'
- ],
- b'uris': [
- b'http://example.com/'
- ]
- }
- ]
- }
- }
- ]
- (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
-
-Unknown protocol is filtered from compatible targets
-
- $ cat > redirects.py << EOF
- > [
- > {
- > b'name': b'target-a',
- > b'protocol': b'http',
- > b'uris': [b'http://example.com/'],
- > },
- > {
- > b'name': b'target-b',
- > b'protocol': b'unknown',
- > b'uris': [b'unknown://example.com/'],
- > },
- > ]
- > EOF
-
- $ sendhttpv2peerhandshake << EOF
- > command capabilities
- > EOF
- creating http peer for wire protocol version 2
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
- s> x-hgproto-1: cbor\r\n
- s> x-hgupgrade-1: exp-http-v2-0003\r\n
- s> accept: application/mercurial-0.1\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-cbor\r\n
- s> Content-Length: 2316\r\n
- s> \r\n
- s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0003\xa5Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1LsparserevlogHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x82\xa3DnameHtarget-aHprotocolDhttpDuris\x81Shttp://example.com/\xa3DnameHtarget-bHprotocolGunknownDuris\x81Vunknown://example.com/Nv1capabilitiesY\x01\xe4batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- (remote redirect target target-a is compatible)
- (remote redirect target target-b uses unsupported protocol: unknown)
- sending capabilities command
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> content-length: 111\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> \x1c\x00\x00\x01\x00\x01\x01\x82\xa1Pcontentencodings\x81HidentityC\x00\x00\x01\x00\x01\x00\x11\xa2DnameLcapabilitiesHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81Htarget-a
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x01\x00\x02\x01\x92
- s> Hidentity
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x01\x00\x02\x041
- s> \xa1FstatusBok
- s> \r\n
- s> 6f9\r\n
- s> \xf1\x06\x00\x01\x00\x02\x041
- s> \xa5Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1LsparserevlogHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x82\xa3DnameHtarget-aHprotocolDhttpDuris\x81Shttp://example.com/\xa3DnameHtarget-bHprotocolGunknownDuris\x81Vunknown://example.com/
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x01\x00\x02\x002
- s> \r\n
- s> 0\r\n
- s> \r\n
- response: gen[
- {
- b'commands': {
- b'branchmap': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'capabilities': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'changesetdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'bookmarks',
- b'parents',
- b'phase',
- b'revision'
- ])
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filedata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'path': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filesdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'firstchangeset',
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'dict'
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 50000
- },
- b'heads': {
- b'args': {
- b'publiconly': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'known': {
- b'args': {
- b'nodes': {
- b'default': [],
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'listkeys': {
- b'args': {
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'lookup': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'manifestdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'tree': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 100000
- },
- b'pushkey': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- },
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- },
- b'new': {
- b'required': True,
- b'type': b'bytes'
- },
- b'old': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'push'
- ]
- },
- b'rawstorefiledata': {
- b'args': {
- b'files': {
- b'required': True,
- b'type': b'list'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- }
- },
- b'framingmediatypes': [
- b'application/mercurial-exp-framing-0006'
- ],
- b'pathfilterprefixes': set([
- b'path:',
- b'rootfilesin:'
- ]),
- b'rawrepoformats': [
- b'generaldelta',
- b'revlogv1',
- b'sparserevlog'
- ],
- b'redirect': {
- b'hashes': [
- b'sha256',
- b'sha1'
- ],
- b'targets': [
- {
- b'name': b'target-a',
- b'protocol': b'http',
- b'uris': [
- b'http://example.com/'
- ]
- },
- {
- b'name': b'target-b',
- b'protocol': b'unknown',
- b'uris': [
- b'unknown://example.com/'
- ]
- }
- ]
- }
- }
- ]
- (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
-
-Missing SNI support filters targets that require SNI
-
- $ cat > nosni.py << EOF
- > from mercurial import sslutil
- > sslutil.hassni = False
- > EOF
- $ cat >> $HGRCPATH << EOF
- > [extensions]
- > nosni=`pwd`/nosni.py
- > EOF
-
- $ cat > redirects.py << EOF
- > [
- > {
- > b'name': b'target-bad-tls',
- > b'protocol': b'https',
- > b'uris': [b'https://example.com/'],
- > b'snirequired': True,
- > },
- > ]
- > EOF
-
- $ sendhttpv2peerhandshake << EOF
- > command capabilities
- > EOF
- creating http peer for wire protocol version 2
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
- s> x-hgproto-1: cbor\r\n
- s> x-hgupgrade-1: exp-http-v2-0003\r\n
- s> accept: application/mercurial-0.1\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-cbor\r\n
- s> Content-Length: 2276\r\n
- s> \r\n
- s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0003\xa5Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1LsparserevlogHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81\xa4DnameNtarget-bad-tlsHprotocolEhttpsKsnirequired\xf5Duris\x81Thttps://example.com/Nv1capabilitiesY\x01\xe4batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- (redirect target target-bad-tls requires SNI, which is unsupported)
- sending capabilities command
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> content-length: 102\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> \x1c\x00\x00\x01\x00\x01\x01\x82\xa1Pcontentencodings\x81Hidentity:\x00\x00\x01\x00\x01\x00\x11\xa2DnameLcapabilitiesHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x80
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x01\x00\x02\x01\x92
- s> Hidentity
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x01\x00\x02\x041
- s> \xa1FstatusBok
- s> \r\n
- s> 6d1\r\n
- s> \xc9\x06\x00\x01\x00\x02\x041
- s> \xa5Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1LsparserevlogHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81\xa4DnameNtarget-bad-tlsHprotocolEhttpsKsnirequired\xf5Duris\x81Thttps://example.com/
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x01\x00\x02\x002
- s> \r\n
- s> 0\r\n
- s> \r\n
- response: gen[
- {
- b'commands': {
- b'branchmap': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'capabilities': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'changesetdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'bookmarks',
- b'parents',
- b'phase',
- b'revision'
- ])
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filedata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'path': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filesdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'firstchangeset',
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'dict'
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 50000
- },
- b'heads': {
- b'args': {
- b'publiconly': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'known': {
- b'args': {
- b'nodes': {
- b'default': [],
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'listkeys': {
- b'args': {
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'lookup': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'manifestdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'tree': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 100000
- },
- b'pushkey': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- },
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- },
- b'new': {
- b'required': True,
- b'type': b'bytes'
- },
- b'old': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'push'
- ]
- },
- b'rawstorefiledata': {
- b'args': {
- b'files': {
- b'required': True,
- b'type': b'list'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- }
- },
- b'framingmediatypes': [
- b'application/mercurial-exp-framing-0006'
- ],
- b'pathfilterprefixes': set([
- b'path:',
- b'rootfilesin:'
- ]),
- b'rawrepoformats': [
- b'generaldelta',
- b'revlogv1',
- b'sparserevlog'
- ],
- b'redirect': {
- b'hashes': [
- b'sha256',
- b'sha1'
- ],
- b'targets': [
- {
- b'name': b'target-bad-tls',
- b'protocol': b'https',
- b'snirequired': True,
- b'uris': [
- b'https://example.com/'
- ]
- }
- ]
- }
- }
- ]
- (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ cat >> $HGRCPATH << EOF
- > [extensions]
- > nosni=!
- > EOF
-
-Unknown tls value is filtered from compatible targets
-
- $ cat > redirects.py << EOF
- > [
- > {
- > b'name': b'target-bad-tls',
- > b'protocol': b'https',
- > b'uris': [b'https://example.com/'],
- > b'tlsversions': [b'42', b'39'],
- > },
- > ]
- > EOF
-
- $ sendhttpv2peerhandshake << EOF
- > command capabilities
- > EOF
- creating http peer for wire protocol version 2
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /?cmd=capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
- s> x-hgproto-1: cbor\r\n
- s> x-hgupgrade-1: exp-http-v2-0003\r\n
- s> accept: application/mercurial-0.1\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-cbor\r\n
- s> Content-Length: 2282\r\n
- s> \r\n
- s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0003\xa5Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1LsparserevlogHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81\xa4DnameNtarget-bad-tlsHprotocolEhttpsKtlsversions\x82B42B39Duris\x81Thttps://example.com/Nv1capabilitiesY\x01\xe4batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
- (remote redirect target target-bad-tls requires unsupported TLS versions: 39, 42)
- sending capabilities command
- s> setsockopt(6, 1, 1) -> None (?)
- s> POST /api/exp-http-v2-0003/ro/capabilities HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> accept: application/mercurial-exp-framing-0006\r\n
- s> content-type: application/mercurial-exp-framing-0006\r\n
- s> content-length: 102\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> user-agent: Mercurial debugwireproto\r\n
- s> \r\n
- s> \x1c\x00\x00\x01\x00\x01\x01\x82\xa1Pcontentencodings\x81Hidentity:\x00\x00\x01\x00\x01\x00\x11\xa2DnameLcapabilitiesHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x80
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-exp-framing-0006\r\n
- s> Transfer-Encoding: chunked\r\n
- s> \r\n
- s> 11\r\n
- s> \t\x00\x00\x01\x00\x02\x01\x92
- s> Hidentity
- s> \r\n
- s> 13\r\n
- s> \x0b\x00\x00\x01\x00\x02\x041
- s> \xa1FstatusBok
- s> \r\n
- s> 6d7\r\n
- s> \xcf\x06\x00\x01\x00\x02\x041
- s> \xa5Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1LsparserevlogHredirect\xa2Fhashes\x82Fsha256Dsha1Gtargets\x81\xa4DnameNtarget-bad-tlsHprotocolEhttpsKtlsversions\x82B42B39Duris\x81Thttps://example.com/
- s> \r\n
- s> 8\r\n
- s> \x00\x00\x00\x01\x00\x02\x002
- s> \r\n
- s> 0\r\n
- s> \r\n
- response: gen[
- {
- b'commands': {
- b'branchmap': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'capabilities': {
- b'args': {},
- b'permissions': [
- b'pull'
- ]
- },
- b'changesetdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'bookmarks',
- b'parents',
- b'phase',
- b'revision'
- ])
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filedata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'path': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'filesdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'firstchangeset',
- b'linknode',
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'dict'
- },
- b'revisions': {
- b'required': True,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 50000
- },
- b'heads': {
- b'args': {
- b'publiconly': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'known': {
- b'args': {
- b'nodes': {
- b'default': [],
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'listkeys': {
- b'args': {
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'lookup': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ]
- },
- b'manifestdata': {
- b'args': {
- b'fields': {
- b'default': set([]),
- b'required': False,
- b'type': b'set',
- b'validvalues': set([
- b'parents',
- b'revision'
- ])
- },
- b'haveparents': {
- b'default': False,
- b'required': False,
- b'type': b'bool'
- },
- b'nodes': {
- b'required': True,
- b'type': b'list'
- },
- b'tree': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'pull'
- ],
- b'recommendedbatchsize': 100000
- },
- b'pushkey': {
- b'args': {
- b'key': {
- b'required': True,
- b'type': b'bytes'
- },
- b'namespace': {
- b'required': True,
- b'type': b'bytes'
- },
- b'new': {
- b'required': True,
- b'type': b'bytes'
- },
- b'old': {
- b'required': True,
- b'type': b'bytes'
- }
- },
- b'permissions': [
- b'push'
- ]
- },
- b'rawstorefiledata': {
- b'args': {
- b'files': {
- b'required': True,
- b'type': b'list'
- },
- b'pathfilter': {
- b'default': None,
- b'required': False,
- b'type': b'list'
- }
- },
- b'permissions': [
- b'pull'
- ]
- }
- },
- b'framingmediatypes': [
- b'application/mercurial-exp-framing-0006'
- ],
- b'pathfilterprefixes': set([
- b'path:',
- b'rootfilesin:'
- ]),
- b'rawrepoformats': [
- b'generaldelta',
- b'revlogv1',
- b'sparserevlog'
- ],
- b'redirect': {
- b'hashes': [
- b'sha256',
- b'sha1'
- ],
- b'targets': [
- {
- b'name': b'target-bad-tls',
- b'protocol': b'https',
- b'tlsversions': [
- b'42',
- b'39'
- ],
- b'uris': [
- b'https://example.com/'
- ]
- }
- ]
- }
- }
- ]
- (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
-
-Set up the server to issue content redirects to its built-in API server.
-
- $ cat > redirects.py << EOF
- > [
- > {
- > b'name': b'local',
- > b'protocol': b'http',
- > b'uris': [b'http://example.com/'],
- > },
- > ]
- > EOF
-
-Request to eventual cache URL should return 404 (validating the cache server works)
-
- $ sendhttpraw << EOF
- > httprequest GET api/simplecache/missingkey
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /api/simplecache/missingkey HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 404 Not Found\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: text/plain\r\n
- s> Content-Length: 22\r\n
- s> \r\n
- s> key not found in cache
-
-Send a cacheable request
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x99\x2f\x47\x79\x02\x9a\x3d\xf8\xd0\x66\x6d\x00\xbb\x92\x4f\x69\x63\x4e\x26\x41']
- > tree eval:b''
- > fields eval:[b'parents']
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- }
- ]
-
-Cached entry should be available on server
-
- $ sendhttpraw << EOF
- > httprequest GET api/simplecache/47abb8efa5f01b8964d74917793ad2464db0fa2c
- > user-agent: test
- > EOF
- using raw connection to peer
- s> setsockopt(6, 1, 1) -> None (?)
- s> GET /api/simplecache/47abb8efa5f01b8964d74917793ad2464db0fa2c HTTP/1.1\r\n
- s> Accept-Encoding: identity\r\n
- s> user-agent: test\r\n
- s> host: $LOCALIP:$HGPORT\r\n (glob)
- s> \r\n
- s> makefile('rb', None)
- s> HTTP/1.1 200 OK\r\n
- s> Server: testing stub value\r\n
- s> Date: $HTTP_DATE$\r\n
- s> Content-Type: application/mercurial-cbor\r\n
- s> Content-Length: 91\r\n
- s> \r\n
- s> \xa1Jtotalitems\x01\xa2DnodeT\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&AGparents\x82T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
- cbor> [
- {
- b'totalitems': 1
- },
- {
- b'node': b'\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- }
- ]
-
-2nd request should result in content redirect response
-
- $ sendhttpv2peer << EOF
- > command manifestdata
- > nodes eval:[b'\x99\x2f\x47\x79\x02\x9a\x3d\xf8\xd0\x66\x6d\x00\xbb\x92\x4f\x69\x63\x4e\x26\x41']
- > tree eval:b''
- > fields eval:[b'parents']
- > EOF
- creating http peer for wire protocol version 2
- sending manifestdata command
- response: gen[
- {
- b'totalitems': 1
- },
- {
- b'node': b'\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- b'parents': [
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
- ]
- }
- ]
-
- $ cat error.log
- $ killdaemons.py
-
- $ cat .hg/blackbox.log
- *> cacher constructed for manifestdata (glob)
- *> cache miss for 47abb8efa5f01b8964d74917793ad2464db0fa2c (glob)
- *> storing cache entry for 47abb8efa5f01b8964d74917793ad2464db0fa2c (glob)
- *> cacher constructed for manifestdata (glob)
- *> cache hit for 47abb8efa5f01b8964d74917793ad2464db0fa2c (glob)
- *> sending content redirect for 47abb8efa5f01b8964d74917793ad2464db0fa2c to http://*:$HGPORT/api/simplecache/47abb8efa5f01b8964d74917793ad2464db0fa2c (glob)
--- a/tests/test-wireproto-exchangev2-shallow.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,597 +0,0 @@
-#require sqlite
-
-Tests for wire protocol version 2 exchange.
-Tests in this file should be folded into existing tests once protocol
-v2 has enough features that it can be enabled via #testcase in existing
-tests.
-
- $ . $TESTDIR/wireprotohelpers.sh
- $ enablehttpv2client
- $ cat >> $HGRCPATH << EOF
- > [extensions]
- > sqlitestore =
- > pullext = $TESTDIR/pullext.py
- > [storage]
- > new-repo-backend=sqlite
- > EOF
-
-Configure a server
-
- $ hg init server-basic
- $ enablehttpv2 server-basic
- $ cd server-basic
- $ mkdir dir0 dir1
- $ echo a0 > a
- $ echo b0 > b
- $ hg -q commit -A -m 'commit 0'
- $ echo c0 > dir0/c
- $ echo d0 > dir0/d
- $ hg -q commit -A -m 'commit 1'
- $ echo e0 > dir1/e
- $ echo f0 > dir1/f
- $ hg -q commit -A -m 'commit 2'
- $ echo c1 > dir0/c
- $ echo e1 > dir1/e
- $ hg commit -m 'commit 3'
- $ echo c2 > dir0/c
- $ echo e2 > dir1/e
- $ echo f1 > dir1/f
- $ hg commit -m 'commit 4'
- $ echo a1 > a
- $ echo b1 > b
- $ hg commit -m 'commit 5'
-
- $ hg log -G -T '{node} {desc}'
- @ 93a8bd067ed2840d9aa810ad598168383a3a2c3a commit 5
- |
- o dc666cf9ecf3d94e6b830f30e5f1272e2a9164d9 commit 4
- |
- o 97765fc3cd624fd1fa0176932c21ffd16adf432e commit 3
- |
- o 47fe012ab237a8c7fc0c78f9f26d5866eef3f825 commit 2
- |
- o b709380892b193c1091d3a817f706052e346821b commit 1
- |
- o 3390ef850073fbc2f0dfff2244342c8e9229013a commit 0
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
- $ cd ..
-
-Shallow clone pulls down latest revision of every file
-
- $ hg --debug clone --depth 1 http://localhost:$HGPORT client-shallow-1
- using http://localhost:$HGPORT/
- sending capabilities command
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': []
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\x93\xa8\xbd\x06~\xd2\x84\r\x9a\xa8\x10\xadY\x81h8::,:'
- ],
- 'roots': [],
- 'type': 'changesetdagrange'
- }
- ]
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1170; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset 3390ef850073
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset b709380892b1
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset 47fe012ab237
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset 97765fc3cd62
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset dc666cf9ecf3
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset 93a8bd067ed2
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- checking for updated bookmarks
- sending 1 commands
- sending command manifestdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'nodes': [
- '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- '|2 \x1a\xa3\xa1R\xa9\xe6\xa9"+?\xa8\xd0\xe3\x0f\xc2V\xe8',
- '\x8d\xd0W<\x7f\xaf\xe2\x04F\xcc\xea\xac\x05N\xea\xa4x\x91M\xdb',
- '113\x85\xf2!\x8b\x08^\xb2Z\x821\x1e*\xdd\x0e\xeb\x8c3',
- 'H]O\xc2`\xef\\\xb9\xc0p6\x88K\x00k\x11\x0ej\xdby',
- '\xd9;\xc4\x0b\x0e*GMp\xee\xf7}^\x91/f\x7fSd\x83'
- ],
- 'tree': ''
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1515; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'linknode',
- 'parents',
- 'revision'
- ]),
- 'haveparents': False,
- 'revisions': [
- {
- 'nodes': [
- '\x93\xa8\xbd\x06~\xd2\x84\r\x9a\xa8\x10\xadY\x81h8::,:'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1005; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- updating the branch cache
- new changesets 3390ef850073:93a8bd067ed2
- updating to branch default
- resolving manifests
- branchmerge: False, force: False, partial: False
- ancestor: 000000000000, local: 000000000000+, remote: 93a8bd067ed2
- a: remote created -> g
- getting a
- b: remote created -> g
- getting b
- dir0/c: remote created -> g
- getting dir0/c
- dir0/d: remote created -> g
- getting dir0/d
- dir1/e: remote created -> g
- getting dir1/e
- dir1/f: remote created -> g
- getting dir1/f
- 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
- updating the branch cache
- (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
-
-#if chg
- $ hg --kill-chg-daemon
- $ sleep 2
-#endif
- $ sqlite3 -line client-shallow-1/.hg/store/db.sqlite << EOF
- > SELECT id, path, revnum, node, p1rev, p2rev, linkrev, flags FROM filedata ORDER BY id ASC;
- > EOF
- id = 1
- path = a
- revnum = 0
- node = \x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc (esc)
- p1rev = -1
- p2rev = -1
- linkrev = 5
- flags = 2
-
- id = 2
- path = b
- revnum = 0
- node = \xb1zk\xd3g=\x9a\xb8\xce\xd5\x81\xa2 \xf6/=\xa5\xccEx (esc)
- p1rev = -1
- p2rev = -1
- linkrev = 5
- flags = 2
-
- id = 3
- path = dir0/c
- revnum = 0
- node = I\x1d\xa1\xbb\x89\xeax\xc0\xc0\xa2s[\x16\xce}\x93\x1d\xc8\xe2\r (esc)
- p1rev = -1
- p2rev = -1
- linkrev = 5
- flags = 2
-
- id = 4
- path = dir0/d
- revnum = 0
- node = S\x82\x06\xdc\x97\x1eR\x15@\xd6\x84:\xbf\xe6\xd1`2\xf6\xd4& (esc)
- p1rev = -1
- p2rev = -1
- linkrev = 5
- flags = 0
-
- id = 5
- path = dir1/e
- revnum = 0
- node = ]\xf3\xac\xd8\xd0\xc7\xfaP\x98\xd0'\x9a\x044\xc3\x02\x9e+x\xe1 (esc)
- p1rev = -1
- p2rev = -1
- linkrev = 5
- flags = 2
-
- id = 6
- path = dir1/f
- revnum = 0
- node = (\xc7v\xae\x08\xd0\xd5^\xb4\x06H\xb4\x01\xb9\x0f\xf5DH4\x8e (esc)
- p1rev = -1
- p2rev = -1
- linkrev = 5
- flags = 2
-
-Test a shallow clone with only some files
-
- $ hg --debug clone --depth 1 --include dir0/ http://localhost:$HGPORT client-shallow-narrow-1
- using http://localhost:$HGPORT/
- sending capabilities command
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': []
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\x93\xa8\xbd\x06~\xd2\x84\r\x9a\xa8\x10\xadY\x81h8::,:'
- ],
- 'roots': [],
- 'type': 'changesetdagrange'
- }
- ]
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1170; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset 3390ef850073
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset b709380892b1
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset 47fe012ab237
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset 97765fc3cd62
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset dc666cf9ecf3
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset 93a8bd067ed2
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- checking for updated bookmarks
- sending 1 commands
- sending command manifestdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'nodes': [
- '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- '|2 \x1a\xa3\xa1R\xa9\xe6\xa9"+?\xa8\xd0\xe3\x0f\xc2V\xe8',
- '\x8d\xd0W<\x7f\xaf\xe2\x04F\xcc\xea\xac\x05N\xea\xa4x\x91M\xdb',
- '113\x85\xf2!\x8b\x08^\xb2Z\x821\x1e*\xdd\x0e\xeb\x8c3',
- 'H]O\xc2`\xef\\\xb9\xc0p6\x88K\x00k\x11\x0ej\xdby',
- '\xd9;\xc4\x0b\x0e*GMp\xee\xf7}^\x91/f\x7fSd\x83'
- ],
- 'tree': ''
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1515; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'linknode',
- 'parents',
- 'revision'
- ]),
- 'haveparents': False,
- 'pathfilter': {
- 'include': [
- 'path:dir0'
- ]
- },
- 'revisions': [
- {
- 'nodes': [
- '\x93\xa8\xbd\x06~\xd2\x84\r\x9a\xa8\x10\xadY\x81h8::,:'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=355; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- updating the branch cache
- new changesets 3390ef850073:93a8bd067ed2
- updating to branch default
- resolving manifests
- branchmerge: False, force: False, partial: False
- ancestor: 000000000000, local: 000000000000+, remote: 93a8bd067ed2
- dir0/c: remote created -> g
- getting dir0/c
- dir0/d: remote created -> g
- getting dir0/d
- 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
- updating the branch cache
- (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
-
-#if chg
- $ hg --kill-chg-daemon
- $ sleep 2
-#endif
- $ sqlite3 -line client-shallow-narrow-1/.hg/store/db.sqlite << EOF
- > SELECT id, path, revnum, node, p1rev, p2rev, linkrev, flags FROM filedata ORDER BY id ASC;
- > EOF
- id = 1
- path = dir0/c
- revnum = 0
- node = I\x1d\xa1\xbb\x89\xeax\xc0\xc0\xa2s[\x16\xce}\x93\x1d\xc8\xe2\r (esc)
- p1rev = -1
- p2rev = -1
- linkrev = 5
- flags = 2
-
- id = 2
- path = dir0/d
- revnum = 0
- node = S\x82\x06\xdc\x97\x1eR\x15@\xd6\x84:\xbf\xe6\xd1`2\xf6\xd4& (esc)
- p1rev = -1
- p2rev = -1
- linkrev = 5
- flags = 0
-
-Cloning an old revision with depth=1 works
-
- $ hg --debug clone --depth 1 -r 97765fc3cd624fd1fa0176932c21ffd16adf432e http://localhost:$HGPORT client-shallow-2
- using http://localhost:$HGPORT/
- sending capabilities command
- sending 1 commands
- sending command lookup: {
- 'key': '97765fc3cd624fd1fa0176932c21ffd16adf432e'
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=21; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': []
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'roots': [],
- 'type': 'changesetdagrange'
- }
- ]
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=783; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset 3390ef850073
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset b709380892b1
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset 47fe012ab237
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset 97765fc3cd62
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- checking for updated bookmarks
- sending 1 commands
- sending command manifestdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'nodes': [
- '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- '|2 \x1a\xa3\xa1R\xa9\xe6\xa9"+?\xa8\xd0\xe3\x0f\xc2V\xe8',
- '\x8d\xd0W<\x7f\xaf\xe2\x04F\xcc\xea\xac\x05N\xea\xa4x\x91M\xdb',
- '113\x85\xf2!\x8b\x08^\xb2Z\x821\x1e*\xdd\x0e\xeb\x8c3'
- ],
- 'tree': ''
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=967; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'linknode',
- 'parents',
- 'revision'
- ]),
- 'haveparents': False,
- 'revisions': [
- {
- 'nodes': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1005; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- updating the branch cache
- new changesets 3390ef850073:97765fc3cd62
- updating to branch default
- resolving manifests
- branchmerge: False, force: False, partial: False
- ancestor: 000000000000, local: 000000000000+, remote: 97765fc3cd62
- a: remote created -> g
- getting a
- b: remote created -> g
- getting b
- dir0/c: remote created -> g
- getting dir0/c
- dir0/d: remote created -> g
- getting dir0/d
- dir1/e: remote created -> g
- getting dir1/e
- dir1/f: remote created -> g
- getting dir1/f
- 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
- updating the branch cache
- (sent 6 HTTP requests and * bytes; received * bytes in responses) (glob)
-
-Incremental pull of shallow clone fetches new changesets
-
- $ hg --cwd client-shallow-2 --debug pull http://localhost:$HGPORT
- pulling from http://localhost:$HGPORT/
- using http://localhost:$HGPORT/
- sending capabilities command
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ]
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=2; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- searching for changes
- all local changesets known remotely
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\x93\xa8\xbd\x06~\xd2\x84\r\x9a\xa8\x10\xadY\x81h8::,:'
- ],
- 'roots': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'type': 'changesetdagrange'
- }
- ]
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=400; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset dc666cf9ecf3
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- add changeset 93a8bd067ed2
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos) (?)
- checking for updated bookmarks
- sending 1 commands
- sending command manifestdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'nodes': [
- 'H]O\xc2`\xef\\\xb9\xc0p6\x88K\x00k\x11\x0ej\xdby',
- '\xd9;\xc4\x0b\x0e*GMp\xee\xf7}^\x91/f\x7fSd\x83'
- ],
- 'tree': ''
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=561; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'linknode',
- 'parents',
- 'revision'
- ]),
- 'haveparents': False,
- 'revisions': [
- {
- 'nodes': [
- '\xdcfl\xf9\xec\xf3\xd9Nk\x83\x0f0\xe5\xf1\'.*\x91d\xd9',
- '\x93\xa8\xbd\x06~\xd2\x84\r\x9a\xa8\x10\xadY\x81h8::,:'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1373; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- updating the branch cache
- new changesets dc666cf9ecf3:93a8bd067ed2
- (run 'hg update' to get a working copy)
- (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ hg --cwd client-shallow-2 up tip
- merging dir0/c
- merging dir1/e
- 3 files updated, 2 files merged, 0 files removed, 0 files unresolved
--- a/tests/test-wireproto-exchangev2.t Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1392 +0,0 @@
-Tests for wire protocol version 2 exchange.
-Tests in this file should be folded into existing tests once protocol
-v2 has enough features that it can be enabled via #testcase in existing
-tests.
-
- $ . $TESTDIR/wireprotohelpers.sh
- $ enablehttpv2client
-
- $ hg init server-simple
- $ enablehttpv2 server-simple
- $ cd server-simple
- $ cat >> .hg/hgrc << EOF
- > [phases]
- > publish = false
- > EOF
- $ echo a0 > a
- $ echo b0 > b
- $ hg -q commit -A -m 'commit 0'
-
- $ echo a1 > a
- $ hg commit -m 'commit 1'
- $ hg phase --public -r .
- $ echo a2 > a
- $ hg commit -m 'commit 2'
-
- $ hg -q up -r 0
- $ echo b1 > b
- $ hg -q commit -m 'head 2 commit 1'
- $ echo b2 > b
- $ hg -q commit -m 'head 2 commit 2'
-
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
- $ cd ..
-
-Test basic clone
-
-Output is flaky, save it in a file and check part independently
- $ hg --debug clone -U http://localhost:$HGPORT client-simple > clone-output
-
- $ cat clone-output | grep -v "received frame"
- using http://localhost:$HGPORT/
- sending capabilities command
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': []
- }
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\xca\xa2\xa4eE\x1d\xd1\xfa\xcd\xa0\xf5\xb1#\x12\xc3UXA\x88\xa1',
- '\xcd%4vk\xec\xe18\xc7\xc1\xaf\xdch%0/\x0fb\xd8\x1f'
- ],
- 'roots': [],
- 'type': 'changesetdagrange'
- }
- ]
- }
- add changeset 3390ef850073
- add changeset 4432d83626e8
- add changeset cd2534766bec
- add changeset e96ae20f4188
- add changeset caa2a465451d
- checking for updated bookmarks
- sending 1 commands
- sending command manifestdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'nodes': [
- '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- '\xa9\x88\xfbCX>\x87\x1d\x1e\xd5u\x0e\xe0t\xc6\xd8@\xbb\xbf\xc8',
- '\xec\x80NH\x8c \x88\xc25\t\x9a\x10 u\x13\xbe\xcd\xc3\xdd\xa5',
- '\x04\\\x7f9\'\xda\x13\xe7Z\xf8\xf0\xe4\xf0HI\xe4a\xa9x\x0f',
- '7\x9c\xb0\xc2\xe6d\\y\xdd\xc5\x9a\x1dG\'\xa9\xfb\x83\n\xeb&'
- ],
- 'tree': ''
- }
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'revisions': [
- {
- 'nodes': [
- '3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
- 'D2\xd86&\xe8\xa9\x86U\xf0b\xec\x1f*C\xb0\x7f\x7f\xbb\xb0',
- '\xcd%4vk\xec\xe18\xc7\xc1\xaf\xdch%0/\x0fb\xd8\x1f',
- '\xe9j\xe2\x0fA\x88H{\x9a\xe4\xef9A\xc2|\x81\x141F\xe5',
- '\xca\xa2\xa4eE\x1d\xd1\xfa\xcd\xa0\xf5\xb1#\x12\xc3UXA\x88\xa1'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- updating the branch cache
- new changesets 3390ef850073:caa2a465451d (3 drafts)
- updating the branch cache
- (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ cat clone-output | grep "received frame"
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=43; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=941; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=992; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=901; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
-
- $ rm clone-output
-
-All changesets should have been transferred
-
- $ hg -R client-simple debugindex -c
- rev linkrev nodeid p1 p2
- 0 0 3390ef850073 000000000000 000000000000
- 1 1 4432d83626e8 3390ef850073 000000000000
- 2 2 cd2534766bec 4432d83626e8 000000000000
- 3 3 e96ae20f4188 3390ef850073 000000000000
- 4 4 caa2a465451d e96ae20f4188 000000000000
-
- $ hg -R client-simple log -G -T '{rev} {node} {phase}\n'
- o 4 caa2a465451dd1facda0f5b12312c355584188a1 draft
- |
- o 3 e96ae20f4188487b9ae4ef3941c27c81143146e5 draft
- |
- | o 2 cd2534766bece138c7c1afdc6825302f0f62d81f draft
- | |
- | o 1 4432d83626e8a98655f062ec1f2a43b07f7fbbb0 public
- |/
- o 0 3390ef850073fbc2f0dfff2244342c8e9229013a public
-
-
-All manifests should have been transferred
-
- $ hg -R client-simple debugindex -m
- rev linkrev nodeid p1 p2
- 0 0 992f4779029a 000000000000 000000000000
- 1 1 a988fb43583e 992f4779029a 000000000000
- 2 2 ec804e488c20 a988fb43583e 000000000000
- 3 3 045c7f3927da 992f4779029a 000000000000
- 4 4 379cb0c2e664 045c7f3927da 000000000000
-
-Cloning only a specific revision works
-
-Output is flaky, save it in a file and check part independently
- $ hg --debug clone -U -r 4432d83626e8 http://localhost:$HGPORT client-singlehead > clone-output
-
- $ cat clone-output | grep -v "received frame"
- using http://localhost:$HGPORT/
- sending capabilities command
- sending 1 commands
- sending command lookup: {
- 'key': '4432d83626e8'
- }
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': []
- }
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- 'D2\xd86&\xe8\xa9\x86U\xf0b\xec\x1f*C\xb0\x7f\x7f\xbb\xb0'
- ],
- 'roots': [],
- 'type': 'changesetdagrange'
- }
- ]
- }
- add changeset 3390ef850073
- add changeset 4432d83626e8
- checking for updated bookmarks
- sending 1 commands
- sending command manifestdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'nodes': [
- '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- '\xa9\x88\xfbCX>\x87\x1d\x1e\xd5u\x0e\xe0t\xc6\xd8@\xbb\xbf\xc8'
- ],
- 'tree': ''
- }
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'revisions': [
- {
- 'nodes': [
- '3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
- 'D2\xd86&\xe8\xa9\x86U\xf0b\xec\x1f*C\xb0\x7f\x7f\xbb\xb0'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- updating the branch cache
- new changesets 3390ef850073:4432d83626e8
- updating the branch cache
- (sent 6 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ cat clone-output | grep "received frame"
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=21; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=43; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=381; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=404; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=439; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
-
- $ rm clone-output
-
- $ cd client-singlehead
-
- $ hg log -G -T '{rev} {node} {phase}\n'
- o 1 4432d83626e8a98655f062ec1f2a43b07f7fbbb0 public
- |
- o 0 3390ef850073fbc2f0dfff2244342c8e9229013a public
-
-
- $ hg debugindex -m
- rev linkrev nodeid p1 p2
- 0 0 992f4779029a 000000000000 000000000000
- 1 1 a988fb43583e 992f4779029a 000000000000
-
-Incremental pull works
-
-Output is flaky, save it in a file and check part independently
- $ hg --debug pull > pull-output
-
- $ cat pull-output | grep -v "received frame"
- pulling from http://localhost:$HGPORT/
- using http://localhost:$HGPORT/
- sending capabilities command
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': [
- 'D2\xd86&\xe8\xa9\x86U\xf0b\xec\x1f*C\xb0\x7f\x7f\xbb\xb0'
- ]
- }
- searching for changes
- all local changesets known remotely
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\xca\xa2\xa4eE\x1d\xd1\xfa\xcd\xa0\xf5\xb1#\x12\xc3UXA\x88\xa1',
- '\xcd%4vk\xec\xe18\xc7\xc1\xaf\xdch%0/\x0fb\xd8\x1f'
- ],
- 'roots': [
- 'D2\xd86&\xe8\xa9\x86U\xf0b\xec\x1f*C\xb0\x7f\x7f\xbb\xb0'
- ],
- 'type': 'changesetdagrange'
- }
- ]
- }
- add changeset cd2534766bec
- add changeset e96ae20f4188
- add changeset caa2a465451d
- checking for updated bookmarks
- sending 1 commands
- sending command manifestdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'nodes': [
- '\xec\x80NH\x8c \x88\xc25\t\x9a\x10 u\x13\xbe\xcd\xc3\xdd\xa5',
- '\x04\\\x7f9\'\xda\x13\xe7Z\xf8\xf0\xe4\xf0HI\xe4a\xa9x\x0f',
- '7\x9c\xb0\xc2\xe6d\\y\xdd\xc5\x9a\x1dG\'\xa9\xfb\x83\n\xeb&'
- ],
- 'tree': ''
- }
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'revisions': [
- {
- 'nodes': [
- '\xcd%4vk\xec\xe18\xc7\xc1\xaf\xdch%0/\x0fb\xd8\x1f',
- '\xe9j\xe2\x0fA\x88H{\x9a\xe4\xef9A\xc2|\x81\x141F\xe5',
- '\xca\xa2\xa4eE\x1d\xd1\xfa\xcd\xa0\xf5\xb1#\x12\xc3UXA\x88\xa1'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- updating the branch cache
- new changesets cd2534766bec:caa2a465451d (3 drafts)
- (run 'hg update' to get a working copy)
- (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ cat pull-output | grep "received frame"
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=43; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=2; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=573; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=601; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=527; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
-
- $ rm pull-output
-
- $ hg log -G -T '{rev} {node} {phase}\n'
- o 4 caa2a465451dd1facda0f5b12312c355584188a1 draft
- |
- o 3 e96ae20f4188487b9ae4ef3941c27c81143146e5 draft
- |
- | o 2 cd2534766bece138c7c1afdc6825302f0f62d81f draft
- | |
- | o 1 4432d83626e8a98655f062ec1f2a43b07f7fbbb0 public
- |/
- o 0 3390ef850073fbc2f0dfff2244342c8e9229013a public
-
-
- $ hg debugindex -m
- rev linkrev nodeid p1 p2
- 0 0 992f4779029a 000000000000 000000000000
- 1 1 a988fb43583e 992f4779029a 000000000000
- 2 2 ec804e488c20 a988fb43583e 000000000000
- 3 3 045c7f3927da 992f4779029a 000000000000
- 4 4 379cb0c2e664 045c7f3927da 000000000000
-
-Phase-only update works
-TODO this doesn't work
-
- $ hg -R ../server-simple phase --public -r caa2a465451dd
- $ hg --debug pull
- pulling from http://localhost:$HGPORT/
- using http://localhost:$HGPORT/
- sending capabilities command
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': [
- '\xcd%4vk\xec\xe18\xc7\xc1\xaf\xdch%0/\x0fb\xd8\x1f',
- '\xca\xa2\xa4eE\x1d\xd1\xfa\xcd\xa0\xf5\xb1#\x12\xc3UXA\x88\xa1'
- ]
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=43; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=3; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- searching for changes
- all remote heads known locally
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\xca\xa2\xa4eE\x1d\xd1\xfa\xcd\xa0\xf5\xb1#\x12\xc3UXA\x88\xa1',
- '\xcd%4vk\xec\xe18\xc7\xc1\xaf\xdch%0/\x0fb\xd8\x1f'
- ],
- 'roots': [
- '\xca\xa2\xa4eE\x1d\xd1\xfa\xcd\xa0\xf5\xb1#\x12\xc3UXA\x88\xa1',
- '\xcd%4vk\xec\xe18\xc7\xc1\xaf\xdch%0/\x0fb\xd8\x1f'
- ],
- 'type': 'changesetdagrange'
- }
- ]
- }
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=13; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- checking for updated bookmarks
- (run 'hg update' to get a working copy)
- (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ hg log -G -T '{rev} {node} {phase}\n'
- o 4 caa2a465451dd1facda0f5b12312c355584188a1 draft
- |
- o 3 e96ae20f4188487b9ae4ef3941c27c81143146e5 draft
- |
- | o 2 cd2534766bece138c7c1afdc6825302f0f62d81f draft
- | |
- | o 1 4432d83626e8a98655f062ec1f2a43b07f7fbbb0 public
- |/
- o 0 3390ef850073fbc2f0dfff2244342c8e9229013a public
-
-
- $ cd ..
-
-Bookmarks are transferred on clone
-
- $ hg -R server-simple bookmark -r 3390ef850073fbc2f0dfff2244342c8e9229013a book-1
- $ hg -R server-simple bookmark -r cd2534766bece138c7c1afdc6825302f0f62d81f book-2
-
-Output is flaky, save it in a file and check part independently
- $ hg --debug clone -U http://localhost:$HGPORT/ client-bookmarks > clone-output
-
- $ cat clone-output | grep -v "received frame"
- using http://localhost:$HGPORT/
- sending capabilities command
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': []
- }
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\xca\xa2\xa4eE\x1d\xd1\xfa\xcd\xa0\xf5\xb1#\x12\xc3UXA\x88\xa1',
- '\xcd%4vk\xec\xe18\xc7\xc1\xaf\xdch%0/\x0fb\xd8\x1f'
- ],
- 'roots': [],
- 'type': 'changesetdagrange'
- }
- ]
- }
- add changeset 3390ef850073
- add changeset 4432d83626e8
- add changeset cd2534766bec
- add changeset e96ae20f4188
- add changeset caa2a465451d
- checking for updated bookmarks
- adding remote bookmark book-1
- adding remote bookmark book-2
- sending 1 commands
- sending command manifestdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'nodes': [
- '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- '\xa9\x88\xfbCX>\x87\x1d\x1e\xd5u\x0e\xe0t\xc6\xd8@\xbb\xbf\xc8',
- '\xec\x80NH\x8c \x88\xc25\t\x9a\x10 u\x13\xbe\xcd\xc3\xdd\xa5',
- '\x04\\\x7f9\'\xda\x13\xe7Z\xf8\xf0\xe4\xf0HI\xe4a\xa9x\x0f',
- '7\x9c\xb0\xc2\xe6d\\y\xdd\xc5\x9a\x1dG\'\xa9\xfb\x83\n\xeb&'
- ],
- 'tree': ''
- }
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'revisions': [
- {
- 'nodes': [
- '3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
- 'D2\xd86&\xe8\xa9\x86U\xf0b\xec\x1f*C\xb0\x7f\x7f\xbb\xb0',
- '\xcd%4vk\xec\xe18\xc7\xc1\xaf\xdch%0/\x0fb\xd8\x1f',
- '\xe9j\xe2\x0fA\x88H{\x9a\xe4\xef9A\xc2|\x81\x141F\xe5',
- '\xca\xa2\xa4eE\x1d\xd1\xfa\xcd\xa0\xf5\xb1#\x12\xc3UXA\x88\xa1'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- updating the branch cache
- new changesets 3390ef850073:caa2a465451d (1 drafts)
- updating the branch cache
- (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ cat clone-output | grep "received frame"
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=43; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=979; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=992; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=901; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
-
- $ rm clone-output
-
- $ hg -R client-bookmarks bookmarks
- book-1 0:3390ef850073
- book-2 2:cd2534766bec
-
-Server-side bookmark moves are reflected during `hg pull`
-
- $ hg -R server-simple bookmark -r cd2534766bece138c7c1afdc6825302f0f62d81f book-1
- moving bookmark 'book-1' forward from 3390ef850073
-
-Output is flaky, save it in a file and check part independently
- $ hg -R client-bookmarks --debug pull > pull-output
-
- $ cat pull-output | grep -v "received frame"
- pulling from http://localhost:$HGPORT/
- using http://localhost:$HGPORT/
- sending capabilities command
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': [
- '\xcd%4vk\xec\xe18\xc7\xc1\xaf\xdch%0/\x0fb\xd8\x1f',
- '\xca\xa2\xa4eE\x1d\xd1\xfa\xcd\xa0\xf5\xb1#\x12\xc3UXA\x88\xa1'
- ]
- }
- searching for changes
- all remote heads known locally
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\xca\xa2\xa4eE\x1d\xd1\xfa\xcd\xa0\xf5\xb1#\x12\xc3UXA\x88\xa1',
- '\xcd%4vk\xec\xe18\xc7\xc1\xaf\xdch%0/\x0fb\xd8\x1f'
- ],
- 'roots': [
- '\xca\xa2\xa4eE\x1d\xd1\xfa\xcd\xa0\xf5\xb1#\x12\xc3UXA\x88\xa1',
- '\xcd%4vk\xec\xe18\xc7\xc1\xaf\xdch%0/\x0fb\xd8\x1f'
- ],
- 'type': 'changesetdagrange'
- }
- ]
- }
- checking for updated bookmarks
- updating bookmark book-1
- (run 'hg update' to get a working copy)
- (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ cat pull-output | grep "received frame"
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=43; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=3; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=65; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
-
- $ rm pull-output
-
- $ hg -R client-bookmarks bookmarks
- book-1 2:cd2534766bec
- book-2 2:cd2534766bec
-
- $ killdaemons.py
-
-Let's set up a slightly more complicated server
-
- $ hg init server-2
- $ enablehttpv2 server-2
- $ cd server-2
- $ mkdir dir0 dir1
- $ echo a0 > a
- $ echo b0 > b
- $ hg -q commit -A -m 'commit 0'
- $ echo c0 > dir0/c
- $ echo d0 > dir0/d
- $ hg -q commit -A -m 'commit 1'
- $ echo e0 > dir1/e
- $ echo f0 > dir1/f
- $ hg -q commit -A -m 'commit 2'
- $ echo c1 > dir0/c
- $ echo e1 > dir1/e
- $ hg commit -m 'commit 3'
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
-
- $ cd ..
-
-Narrow clone only fetches some files
-
-Output is flaky, save it in a file and check part independently
- $ hg --config extensions.pullext=$TESTDIR/pullext.py --debug clone -U --include dir0/ http://localhost:$HGPORT/ client-narrow-0 > clone-output
-
- $ cat clone-output | grep -v "received frame"
- using http://localhost:$HGPORT/
- sending capabilities command
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': []
- }
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'roots': [],
- 'type': 'changesetdagrange'
- }
- ]
- }
- add changeset 3390ef850073
- add changeset b709380892b1
- add changeset 47fe012ab237
- add changeset 97765fc3cd62
- checking for updated bookmarks
- sending 1 commands
- sending command manifestdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'nodes': [
- '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- '|2 \x1a\xa3\xa1R\xa9\xe6\xa9"+?\xa8\xd0\xe3\x0f\xc2V\xe8',
- '\x8d\xd0W<\x7f\xaf\xe2\x04F\xcc\xea\xac\x05N\xea\xa4x\x91M\xdb',
- '113\x85\xf2!\x8b\x08^\xb2Z\x821\x1e*\xdd\x0e\xeb\x8c3'
- ],
- 'tree': ''
- }
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'pathfilter': {
- 'include': [
- 'path:dir0'
- ]
- },
- 'revisions': [
- {
- 'nodes': [
- '3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
- '\xb7\t8\x08\x92\xb1\x93\xc1\t\x1d:\x81\x7fp`R\xe3F\x82\x1b',
- 'G\xfe\x01*\xb27\xa8\xc7\xfc\x0cx\xf9\xf2mXf\xee\xf3\xf8%',
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- updating the branch cache
- new changesets 3390ef850073:97765fc3cd62
- updating the branch cache
- (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ cat clone-output | grep "received frame"
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=783; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=967; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=449; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
-
- $ rm clone-output
-
-#if reporevlogstore
- $ find client-narrow-0/.hg/store -type f -name '*.i' | sort
- client-narrow-0/.hg/store/00changelog.i
- client-narrow-0/.hg/store/00manifest.i
- client-narrow-0/.hg/store/data/dir0/c.i
- client-narrow-0/.hg/store/data/dir0/d.i
-#endif
-
---exclude by itself works
-
-Output is flaky, save it in a file and check part independently
- $ hg --config extensions.pullext=$TESTDIR/pullext.py --debug clone -U --exclude dir0/ http://localhost:$HGPORT/ client-narrow-1 > clone-output
-
- $ cat clone-output | grep -v "received frame"
- using http://localhost:$HGPORT/
- sending capabilities command
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': []
- }
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'roots': [],
- 'type': 'changesetdagrange'
- }
- ]
- }
- add changeset 3390ef850073
- add changeset b709380892b1
- add changeset 47fe012ab237
- add changeset 97765fc3cd62
- checking for updated bookmarks
- sending 1 commands
- sending command manifestdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'nodes': [
- '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- '|2 \x1a\xa3\xa1R\xa9\xe6\xa9"+?\xa8\xd0\xe3\x0f\xc2V\xe8',
- '\x8d\xd0W<\x7f\xaf\xe2\x04F\xcc\xea\xac\x05N\xea\xa4x\x91M\xdb',
- '113\x85\xf2!\x8b\x08^\xb2Z\x821\x1e*\xdd\x0e\xeb\x8c3'
- ],
- 'tree': ''
- }
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'pathfilter': {
- 'exclude': [
- 'path:dir0'
- ],
- 'include': [
- 'path:.'
- ]
- },
- 'revisions': [
- {
- 'nodes': [
- '3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
- '\xb7\t8\x08\x92\xb1\x93\xc1\t\x1d:\x81\x7fp`R\xe3F\x82\x1b',
- 'G\xfe\x01*\xb27\xa8\xc7\xfc\x0cx\xf9\xf2mXf\xee\xf3\xf8%',
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- updating the branch cache
- new changesets 3390ef850073:97765fc3cd62
- updating the branch cache
- (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ cat clone-output | grep "received frame"
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=783; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=967; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=709; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
-
- $ rm clone-output
-
-#if reporevlogstore
- $ find client-narrow-1/.hg/store -type f -name '*.i' | sort
- client-narrow-1/.hg/store/00changelog.i
- client-narrow-1/.hg/store/00manifest.i
- client-narrow-1/.hg/store/data/a.i
- client-narrow-1/.hg/store/data/b.i
- client-narrow-1/.hg/store/data/dir1/e.i
- client-narrow-1/.hg/store/data/dir1/f.i
-#endif
-
-Mixing --include and --exclude works
-
-Output is flaky, save it in a file and check part independently
- $ hg --config extensions.pullext=$TESTDIR/pullext.py --debug clone -U --include dir0/ --exclude dir0/c http://localhost:$HGPORT/ client-narrow-2 > clone-output
-
- $ cat clone-output | grep -v "received frame"
- using http://localhost:$HGPORT/
- sending capabilities command
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': []
- }
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'roots': [],
- 'type': 'changesetdagrange'
- }
- ]
- }
- add changeset 3390ef850073
- add changeset b709380892b1
- add changeset 47fe012ab237
- add changeset 97765fc3cd62
- checking for updated bookmarks
- sending 1 commands
- sending command manifestdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'nodes': [
- '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- '|2 \x1a\xa3\xa1R\xa9\xe6\xa9"+?\xa8\xd0\xe3\x0f\xc2V\xe8',
- '\x8d\xd0W<\x7f\xaf\xe2\x04F\xcc\xea\xac\x05N\xea\xa4x\x91M\xdb',
- '113\x85\xf2!\x8b\x08^\xb2Z\x821\x1e*\xdd\x0e\xeb\x8c3'
- ],
- 'tree': ''
- }
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'pathfilter': {
- 'exclude': [
- 'path:dir0/c'
- ],
- 'include': [
- 'path:dir0'
- ]
- },
- 'revisions': [
- {
- 'nodes': [
- '3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
- '\xb7\t8\x08\x92\xb1\x93\xc1\t\x1d:\x81\x7fp`R\xe3F\x82\x1b',
- 'G\xfe\x01*\xb27\xa8\xc7\xfc\x0cx\xf9\xf2mXf\xee\xf3\xf8%',
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- updating the branch cache
- new changesets 3390ef850073:97765fc3cd62
- updating the branch cache
- (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ cat clone-output | grep "received frame"
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=783; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=967; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=160; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
-
- $ rm clone-output
-
-#if reporevlogstore
- $ find client-narrow-2/.hg/store -type f -name '*.i' | sort
- client-narrow-2/.hg/store/00changelog.i
- client-narrow-2/.hg/store/00manifest.i
- client-narrow-2/.hg/store/data/dir0/d.i
-#endif
-
---stream will use rawfiledata to transfer changelog and manifestlog, then
-fall through to get files data
-
-Output is flaky, save it in a file and check part independently
- $ hg --debug clone --stream -U http://localhost:$HGPORT client-stream-0 > clone-output
-
- $ cat clone-output | grep -v "received frame"
- using http://localhost:$HGPORT/
- sending capabilities command
- sending 1 commands
- sending command rawstorefiledata: {
- 'files': [
- 'changelog',
- 'manifestlog'
- ]
- }
- updating the branch cache
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ]
- }
- searching for changes
- all remote heads known locally
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'roots': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'type': 'changesetdagrange'
- }
- ]
- }
- checking for updated bookmarks
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'revisions': [
- {
- 'nodes': [
- '3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
- '\xb7\t8\x08\x92\xb1\x93\xc1\t\x1d:\x81\x7fp`R\xe3F\x82\x1b',
- 'G\xfe\x01*\xb27\xa8\xc7\xfc\x0cx\xf9\xf2mXf\xee\xf3\xf8%',
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- updating the branch cache
- (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ cat clone-output | grep "received frame"
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1275; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) (no-zstd !)
- received frame(size=1283; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) (zstd !)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=2; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=13; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1133; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
-
- $ rm clone-output
-
---stream + --include/--exclude will only obtain some files
-
-Output is flaky, save it in a file and check part independently
- $ hg --debug --config extensions.pullext=$TESTDIR/pullext.py clone --stream --include dir0/ -U http://localhost:$HGPORT client-stream-2 > clone-output
-
- $ cat clone-output | grep -v "received frame"
- using http://localhost:$HGPORT/
- sending capabilities command
- sending 1 commands
- sending command rawstorefiledata: {
- 'files': [
- 'changelog',
- 'manifestlog'
- ]
- }
- updating the branch cache
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ]
- }
- searching for changes
- all remote heads known locally
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'roots': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'type': 'changesetdagrange'
- }
- ]
- }
- checking for updated bookmarks
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'pathfilter': {
- 'include': [
- 'path:dir0'
- ]
- },
- 'revisions': [
- {
- 'nodes': [
- '3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
- '\xb7\t8\x08\x92\xb1\x93\xc1\t\x1d:\x81\x7fp`R\xe3F\x82\x1b',
- 'G\xfe\x01*\xb27\xa8\xc7\xfc\x0cx\xf9\xf2mXf\xee\xf3\xf8%',
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- updating the branch cache
- (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ cat clone-output | grep "received frame"
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1275; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) (no-zstd !)
- received frame(size=1283; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation) (zstd !)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=2; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=13; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=449; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
-
- $ rm clone-output
-
-#if reporevlogstore
- $ find client-stream-2/.hg/store -type f -name '*.i' | sort
- client-stream-2/.hg/store/00changelog.i
- client-stream-2/.hg/store/00manifest.i
- client-stream-2/.hg/store/data/dir0/c.i
- client-stream-2/.hg/store/data/dir0/d.i
-#endif
-
-Shallow clone doesn't work with revlogs
-
-Output is flaky, save it in a file and check part independently
- $ hg --debug --config extensions.pullext=$TESTDIR/pullext.py clone --depth 1 -U http://localhost:$HGPORT client-shallow-revlogs > clone-output
- transaction abort!
- rollback completed
- abort: revlog storage does not support missing parents write mode
- [255]
-
- $ cat clone-output | grep -v "received frame"
- using http://localhost:$HGPORT/
- sending capabilities command
- query 1; heads
- sending 2 commands
- sending command heads: {}
- sending command known: {
- 'nodes': []
- }
- sending 1 commands
- sending command changesetdata: {
- 'fields': set([
- 'bookmarks',
- 'parents',
- 'phase',
- 'revision'
- ]),
- 'revisions': [
- {
- 'heads': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'roots': [],
- 'type': 'changesetdagrange'
- }
- ]
- }
- add changeset 3390ef850073
- add changeset b709380892b1
- add changeset 47fe012ab237
- add changeset 97765fc3cd62
- checking for updated bookmarks
- sending 1 commands
- sending command manifestdata: {
- 'fields': set([
- 'parents',
- 'revision'
- ]),
- 'haveparents': True,
- 'nodes': [
- '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
- '|2 \x1a\xa3\xa1R\xa9\xe6\xa9"+?\xa8\xd0\xe3\x0f\xc2V\xe8',
- '\x8d\xd0W<\x7f\xaf\xe2\x04F\xcc\xea\xac\x05N\xea\xa4x\x91M\xdb',
- '113\x85\xf2!\x8b\x08^\xb2Z\x821\x1e*\xdd\x0e\xeb\x8c3'
- ],
- 'tree': ''
- }
- sending 1 commands
- sending command filesdata: {
- 'fields': set([
- 'linknode',
- 'parents',
- 'revision'
- ]),
- 'haveparents': False,
- 'revisions': [
- {
- 'nodes': [
- '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
- ],
- 'type': 'changesetexplicit'
- }
- ]
- }
- (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
-
- $ cat clone-output | grep "received frame"
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=783; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=967; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
- received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
- received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=1005; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
- received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
-
- $ rm clone-output
-
- $ killdaemons.py
-
-Repo with 2 DAG branches introducing same filenode, to test linknode adjustment
-
- $ hg init server-linknode
- $ enablehttpv2 server-linknode
- $ cd server-linknode
- $ touch foo
- $ hg -q commit -Am initial
- $ echo foo > dupe-file
- $ hg commit -Am 'dupe 1'
- adding dupe-file
- $ hg -q up -r 0
- $ echo foo > dupe-file
- $ hg commit -Am 'dupe 2'
- adding dupe-file
- created new head
- $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
- $ cat hg.pid > $DAEMON_PIDS
- $ cd ..
-
-Perform an incremental pull of both heads and ensure linkrev is written out properly
-
- $ hg clone -r 96ee1d7354c4 http://localhost:$HGPORT client-linknode-1
- new changesets 96ee1d7354c4
- updating to branch default
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ cd client-linknode-1
- $ touch extra
- $ hg commit -Am extra
- adding extra
- $ cd ..
-
- $ hg clone -r 96ee1d7354c4 http://localhost:$HGPORT client-linknode-2
- new changesets 96ee1d7354c4
- updating to branch default
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ cd client-linknode-2
- $ touch extra
- $ hg commit -Am extra
- adding extra
- $ cd ..
-
- $ hg -R client-linknode-1 pull -r 1681c33f9f80
- pulling from http://localhost:$HGPORT/
- searching for changes
- new changesets 1681c33f9f80
- (run 'hg update' to get a working copy)
-
-#if reporevlogstore
- $ hg -R client-linknode-1 debugrevlogindex dupe-file
- rev linkrev nodeid p1 p2
- 0 2 2ed2a3912a0b 000000000000 000000000000
-#endif
-
- $ hg -R client-linknode-2 pull -r 639c8990d6a5
- pulling from http://localhost:$HGPORT/
- searching for changes
- new changesets 639c8990d6a5
- (run 'hg update' to get a working copy)
-
-#if reporevlogstore
- $ hg -R client-linknode-2 debugrevlogindex dupe-file
- rev linkrev nodeid p1 p2
- 0 2 2ed2a3912a0b 000000000000 000000000000
-#endif
--- a/tests/wireprotohelpers.sh Thu Dec 30 13:25:44 2021 +0100
+++ b/tests/wireprotohelpers.sh Tue Dec 07 16:44:22 2021 +0100
@@ -1,44 +1,23 @@
-HTTPV2=exp-http-v2-0003
MEDIATYPE=application/mercurial-exp-framing-0006
sendhttpraw() {
hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT/
}
-sendhttpv2peer() {
- hg --config experimental.httppeer.v2-encoder-order=identity debugwireproto --nologhandshake --peer http2 http://$LOCALIP:$HGPORT/
-}
-
-sendhttpv2peerverbose() {
- hg --config experimental.httppeer.v2-encoder-order=identity --verbose debugwireproto --nologhandshake --peer http2 http://$LOCALIP:$HGPORT/
-}
-
-sendhttpv2peerhandshake() {
- hg --config experimental.httppeer.v2-encoder-order=identity --verbose debugwireproto --peer http2 http://$LOCALIP:$HGPORT/
-}
-
cat > dummycommands.py << EOF
from mercurial import (
wireprototypes,
wireprotov1server,
- wireprotov2server,
)
@wireprotov1server.wireprotocommand(b'customreadonly', permission=b'pull')
def customreadonlyv1(repo, proto):
return wireprototypes.bytesresponse(b'customreadonly bytes response')
-@wireprotov2server.wireprotocommand(b'customreadonly', permission=b'pull')
-def customreadonlyv2(repo, proto):
- yield b'customreadonly bytes response'
-
@wireprotov1server.wireprotocommand(b'customreadwrite', permission=b'push')
def customreadwrite(repo, proto):
return wireprototypes.bytesresponse(b'customreadwrite bytes response')
-@wireprotov2server.wireprotocommand(b'customreadwrite', permission=b'push')
-def customreadwritev2(repo, proto):
- yield b'customreadwrite bytes response'
EOF
cat >> $HGRCPATH << EOF
@@ -53,20 +32,3 @@
EOF
}
-enablehttpv2() {
- cat >> $1/.hg/hgrc << EOF
-[experimental]
-web.apiserver = true
-web.api.http-v2 = true
-EOF
-}
-
-enablehttpv2client() {
- cat >> $HGRCPATH << EOF
-[experimental]
-httppeer.advertise-v2 = true
-# So tests are in plain text. Also, zstd isn't available in all installs,
-# which would make tests non-deterministic.
-httppeer.v2-encoder-order = identity
-EOF
-}
--- a/tests/wireprotosimplecache.py Thu Dec 30 13:25:44 2021 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,220 +0,0 @@
-# wireprotosimplecache.py - Extension providing in-memory wire protocol cache
-#
-# Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-from __future__ import absolute_import
-
-from mercurial import (
- extensions,
- registrar,
- util,
- wireprotoserver,
- wireprototypes,
- wireprotov2server,
-)
-from mercurial.interfaces import (
- repository,
- util as interfaceutil,
-)
-from mercurial.utils import stringutil
-
-CACHE = None
-
-configtable = {}
-configitem = registrar.configitem(configtable)
-
-configitem(b'simplecache', b'cacheapi', default=False)
-configitem(b'simplecache', b'cacheobjects', default=False)
-configitem(b'simplecache', b'redirectsfile', default=None)
-
-# API handler that makes cached keys available.
-def handlecacherequest(rctx, req, res, checkperm, urlparts):
- if rctx.repo.ui.configbool(b'simplecache', b'cacheobjects'):
- res.status = b'500 Internal Server Error'
- res.setbodybytes(b'cacheobjects not supported for api server')
- return
-
- if not urlparts:
- res.status = b'200 OK'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(b'simple cache server')
- return
-
- key = b'/'.join(urlparts)
-
- if key not in CACHE:
- res.status = b'404 Not Found'
- res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(b'key not found in cache')
- return
-
- res.status = b'200 OK'
- res.headers[b'Content-Type'] = b'application/mercurial-cbor'
- res.setbodybytes(CACHE[key])
-
-
-def cachedescriptor(req, repo):
- return {}
-
-
-wireprotoserver.API_HANDLERS[b'simplecache'] = {
- b'config': (b'simplecache', b'cacheapi'),
- b'handler': handlecacherequest,
- b'apidescriptor': cachedescriptor,
-}
-
-
-@interfaceutil.implementer(repository.iwireprotocolcommandcacher)
-class memorycacher(object):
- def __init__(
- self, ui, command, encodefn, redirecttargets, redirecthashes, req
- ):
- self.ui = ui
- self.encodefn = encodefn
- self.redirecttargets = redirecttargets
- self.redirecthashes = redirecthashes
- self.req = req
- self.key = None
- self.cacheobjects = ui.configbool(b'simplecache', b'cacheobjects')
- self.cacheapi = ui.configbool(b'simplecache', b'cacheapi')
- self.buffered = []
-
- ui.log(b'simplecache', b'cacher constructed for %s\n', command)
-
- def __enter__(self):
- return self
-
- def __exit__(self, exctype, excvalue, exctb):
- if exctype:
- self.ui.log(b'simplecache', b'cacher exiting due to error\n')
-
- def adjustcachekeystate(self, state):
- # Needed in order to make tests deterministic. Don't copy this
- # pattern for production caches!
- del state[b'repo']
-
- def setcachekey(self, key):
- self.key = key
- return True
-
- def lookup(self):
- if self.key not in CACHE:
- self.ui.log(b'simplecache', b'cache miss for %s\n', self.key)
- return None
-
- entry = CACHE[self.key]
- self.ui.log(b'simplecache', b'cache hit for %s\n', self.key)
-
- redirectable = True
-
- if not self.cacheapi:
- redirectable = False
- elif not self.redirecttargets:
- redirectable = False
- else:
- clienttargets = set(self.redirecttargets)
- ourtargets = {t[b'name'] for t in loadredirecttargets(self.ui)}
-
- # We only ever redirect to a single target (for now). So we don't
- # need to store which target matched.
- if not clienttargets & ourtargets:
- redirectable = False
-
- if redirectable:
- paths = self.req.dispatchparts[:-3]
- paths.append(b'simplecache')
- paths.append(self.key)
-
- url = b'%s/%s' % (self.req.baseurl, b'/'.join(paths))
-
- # url = b'http://example.com/%s' % self.key
- self.ui.log(
- b'simplecache',
- b'sending content redirect for %s to ' b'%s\n',
- self.key,
- url,
- )
- response = wireprototypes.alternatelocationresponse(
- url=url, mediatype=b'application/mercurial-cbor'
- )
-
- return {b'objs': [response]}
-
- if self.cacheobjects:
- return {
- b'objs': entry,
- }
- else:
- return {
- b'objs': [wireprototypes.encodedresponse(entry)],
- }
-
- def onobject(self, obj):
- if self.cacheobjects:
- self.buffered.append(obj)
- else:
- self.buffered.extend(self.encodefn(obj))
-
- yield obj
-
- def onfinished(self):
- self.ui.log(b'simplecache', b'storing cache entry for %s\n', self.key)
- if self.cacheobjects:
- CACHE[self.key] = self.buffered
- else:
- CACHE[self.key] = b''.join(self.buffered)
-
- return []
-
-
-def makeresponsecacher(
- orig,
- repo,
- proto,
- command,
- args,
- objencoderfn,
- redirecttargets,
- redirecthashes,
-):
- return memorycacher(
- repo.ui,
- command,
- objencoderfn,
- redirecttargets,
- redirecthashes,
- proto._req,
- )
-
-
-def loadredirecttargets(ui):
- path = ui.config(b'simplecache', b'redirectsfile')
- if not path:
- return []
-
- with open(path, 'rb') as fh:
- s = fh.read()
-
- return stringutil.evalpythonliteral(s)
-
-
-def getadvertisedredirecttargets(orig, repo, proto):
- return loadredirecttargets(repo.ui)
-
-
-def extsetup(ui):
- global CACHE
-
- CACHE = util.lrucachedict(10000)
-
- extensions.wrapfunction(
- wireprotov2server, b'makeresponsecacher', makeresponsecacher
- )
- extensions.wrapfunction(
- wireprotov2server,
- b'getadvertisedredirecttargets',
- getadvertisedredirecttargets,
- )