##// END OF EJS Templates
persistent-nodemap: introduce a test to highlight possible race...
persistent-nodemap: introduce a test to highlight possible race Weakness in the current file caching of the changelog means that a writer can end up using an outdated docket. This might result in "committed" persistent-nodemap data from a previous writer to be overwritten by a later writer. This break the strong "append only" assumption of the persistent nodemap and can result in confused reader. The race windows are quite narrow. See the test documentation for details. The issues is fixed in the next changeset. Differential Revision: https://phab.mercurial-scm.org/D11481

File last commit:

r48177:9d9eb22b default
r48852:52018f8e stable
Show More
ext-sidedata.py
106 lines | 3.5 KiB | text/x-python | PythonLexer
sidedata: test we can successfully write sidedata...
r43308 # ext-sidedata.py - small extension to test the sidedata logic
#
Raphaël Gomès
sidedata-exchange: rewrite sidedata on-the-fly whenever possible...
r47452 # Copyright 2019 Pierre-Yves David <pierre-yves.david@octobus.net>
sidedata: test we can successfully write sidedata...
r43308 #
# 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 hashlib
import struct
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 from mercurial.node import nullrev
sidedata: test we can successfully write sidedata...
r43308 from mercurial import (
extensions,
Pulkit Goyal
localrepo: move requirements constant to requirements module...
r45933 requirements,
sidedata: test we can successfully write sidedata...
r43308 revlog,
)
upgrade: split actual upgrade code away from the main module...
r46661 from mercurial.upgrade_utils import engine as upgrade_engine
Raphaël Gomès
sidedata: replace sidedata upgrade mechanism with the new one...
r47847 from mercurial.revlogutils import constants
Augie Fackler
formatting: blacken the codebase...
r43346 from mercurial.revlogutils import sidedata
sidedata: test we can successfully write sidedata...
r43308
Augie Fackler
formatting: blacken the codebase...
r43346 def wrapaddrevision(
orig, self, text, transaction, link, p1, p2, *args, **kwargs
):
sidedata: test we can successfully write sidedata...
r43308 if kwargs.get('sidedata') is None:
kwargs['sidedata'] = {}
sd = kwargs['sidedata']
## let's store some arbitrary data just for testing
# text length
sd[sidedata.SD_TEST1] = struct.pack('>I', len(text))
# and sha2 hashes
sha256 = hashlib.sha256(text).digest()
sd[sidedata.SD_TEST2] = struct.pack('>32s', sha256)
return orig(self, text, transaction, link, p1, p2, *args, **kwargs)
Augie Fackler
formatting: blacken the codebase...
r43346
Raphaël Gomès
sidedata: move to new sidedata storage in revlogv2...
r47443 def wrap_revisiondata(orig, self, nodeorrev, *args, **kwargs):
revlog: no longer return sidedata from `_revisiondata`...
r48177 text = orig(self, nodeorrev, *args, **kwargs)
sd = self.sidedata(nodeorrev)
upgrade: allow upgrade to repository using sidedata...
r43404 if getattr(self, 'sidedatanocheck', False):
revlog: no longer return sidedata from `_revisiondata`...
r48177 return text
revlog: replace REVLOGV2 check related to sidedata with `hassidedata` checks...
r47907 if self.hassidedata:
revlog: no longer return sidedata from `_revisiondata`...
r48177 return text
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 if nodeorrev != nullrev and nodeorrev != self.nullid:
Raphaël Gomès
sidedata-exchange: rewrite sidedata on-the-fly whenever possible...
r47452 cat1 = sd.get(sidedata.SD_TEST1)
if cat1 is not None and len(text) != struct.unpack('>I', cat1)[0]:
sidedata: check that the sidedata safely roundtrip...
r43310 raise RuntimeError('text size mismatch')
Raphaël Gomès
sidedata-exchange: rewrite sidedata on-the-fly whenever possible...
r47452 expected = sd.get(sidedata.SD_TEST2)
sidedata: check that the sidedata safely roundtrip...
r43310 got = hashlib.sha256(text).digest()
Raphaël Gomès
sidedata-exchange: rewrite sidedata on-the-fly whenever possible...
r47452 if expected is not None and got != expected:
sidedata: check that the sidedata safely roundtrip...
r43310 raise RuntimeError('sha256 mismatch')
revlog: no longer return sidedata from `_revisiondata`...
r48177 return text
sidedata: check that the sidedata safely roundtrip...
r43310
Augie Fackler
formatting: blacken the codebase...
r43346
Raphaël Gomès
sidedata: replace sidedata upgrade mechanism with the new one...
r47847 def wrapget_sidedata_helpers(orig, srcrepo, dstrepo):
repo, computers, removers = orig(srcrepo, dstrepo)
assert not computers and not removers # deal with composition later
upgrade: allow upgrade to repository using sidedata...
r43404 addedreqs = dstrepo.requirements - srcrepo.requirements
Raphaël Gomès
sidedata: replace sidedata upgrade mechanism with the new one...
r47847
sidedata: use revlogv2 requirement in the test helper...
r47998 if requirements.REVLOGV2_REQUIREMENT in addedreqs:
upgrade: allow upgrade to repository using sidedata...
r43404
Raphaël Gomès
sidedata: replace sidedata upgrade mechanism with the new one...
r47847 def computer(repo, revlog, rev, old_sidedata):
assert not old_sidedata # not supported yet
upgrade: allow upgrade to repository using sidedata...
r43404 update = {}
revlog.sidedatanocheck = True
try:
text = revlog.revision(rev)
finally:
del revlog.sidedatanocheck
## let's store some arbitrary data just for testing
# text length
update[sidedata.SD_TEST1] = struct.pack('>I', len(text))
# and sha2 hashes
sha256 = hashlib.sha256(text).digest()
update[sidedata.SD_TEST2] = struct.pack('>32s', sha256)
Raphaël Gomès
sidedata: replace sidedata upgrade mechanism with the new one...
r47847 return update, (0, 0)
upgrade: allow upgrade to repository using sidedata...
r43404
Raphaël Gomès
sidedata: replace sidedata upgrade mechanism with the new one...
r47847 srcrepo.register_sidedata_computer(
constants.KIND_CHANGELOG,
b"whatever",
(sidedata.SD_TEST1, sidedata.SD_TEST2),
computer,
0,
)
dstrepo.register_wanted_sidedata(b"whatever")
Raphaël Gomès
sidedata: move sidedata-related utils to the dedicated module...
r47848 return sidedata.get_sidedata_helpers(srcrepo, dstrepo._wanted_sidedata)
upgrade: allow upgrade to repository using sidedata...
r43404
sidedata: test we can successfully write sidedata...
r43308 def extsetup(ui):
extensions.wrapfunction(revlog.revlog, 'addrevision', wrapaddrevision)
Raphaël Gomès
sidedata: move to new sidedata storage in revlogv2...
r47443 extensions.wrapfunction(revlog.revlog, '_revisiondata', wrap_revisiondata)
upgrade: allow upgrade to repository using sidedata...
r43404 extensions.wrapfunction(
Raphaël Gomès
sidedata: replace sidedata upgrade mechanism with the new one...
r47847 upgrade_engine, 'get_sidedata_helpers', wrapget_sidedata_helpers
upgrade: allow upgrade to repository using sidedata...
r43404 )
Raphaël Gomès
sidedata-exchange: rewrite sidedata on-the-fly whenever possible...
r47452
def reposetup(ui, repo):
# We don't register sidedata computers because we don't care within these
# tests
repo.register_wanted_sidedata(sidedata.SD_TEST1)
repo.register_wanted_sidedata(sidedata.SD_TEST2)