tests: add tests for server-side linknode adjustment with wireprotov2
The current implementation of linknode serving in wireprotov2 simply
serves up the linkrev/linknode as stored: it doesn't attempt to
adjust the linknode to what the receiver is aware of. This can result
in the client seeing a linknode referencing a changeset that is unknown
to it.
This commit adds test coverage of that scenario.
The tests in test-wireproto-command-filesdata.t demonstrate two failures.
First, the linknode refers to a changeset not in the available set.
Second, the server doesn't send a file revision that it should have
(because of linkrev filtering).
The test in test-wireproto-exchange.t demonstrates that the lack of
a file revision results in a corrupted repository on the client.
Differential Revision: https://phab.mercurial-scm.org/D5404
# Extension dedicated to test patch.diff() upgrade modes
from __future__ import absolute_import
from mercurial import (
error,
patch,
pycompat,
registrar,
scmutil,
)
cmdtable = {}
command = registrar.command(cmdtable)
@command(b'autodiff',
[(b'', b'git', b'', b'git upgrade mode (yes/no/auto/warn/abort)')],
b'[OPTION]... [FILE]...')
def autodiff(ui, repo, *pats, **opts):
opts = pycompat.byteskwargs(opts)
diffopts = patch.difffeatureopts(ui, opts)
git = opts.get(b'git', b'no')
brokenfiles = set()
losedatafn = None
if git in (b'yes', b'no'):
diffopts.git = git == b'yes'
diffopts.upgrade = False
elif git == b'auto':
diffopts.git = False
diffopts.upgrade = True
elif git == b'warn':
diffopts.git = False
diffopts.upgrade = True
def losedatafn(fn=None, **kwargs):
brokenfiles.add(fn)
return True
elif git == b'abort':
diffopts.git = False
diffopts.upgrade = True
def losedatafn(fn=None, **kwargs):
raise error.Abort(b'losing data for %s' % fn)
else:
raise error.Abort(b'--git must be yes, no or auto')
ctx1, ctx2 = scmutil.revpair(repo, [])
m = scmutil.match(ctx2, pats, opts)
it = patch.diff(repo, ctx1.node(), ctx2.node(), match=m, opts=diffopts,
losedatafn=losedatafn)
for chunk in it:
ui.write(chunk)
for fn in sorted(brokenfiles):
ui.write((b'data lost for: %s\n' % fn))