diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py --- a/mercurial/revlogutils/nodemap.py +++ b/mercurial/revlogutils/nodemap.py @@ -10,13 +10,16 @@ import errno import os +import random import re import struct from ..node import hex from .. import ( + encoding, error, + pycompat, util, ) @@ -288,6 +291,45 @@ return hex(os.urandom(ID_SIZE)) +# some special test logic to avoid anoying random output in the test +stable_docket_file = encoding.environ.get(b'HGTEST_DOCKETIDFILE') + +if stable_docket_file: + + def _make_uid(): + try: + with open(stable_docket_file, mode='rb') as f: + seed = f.read().strip() + except IOError as inst: + if inst.errno != errno.ENOENT: + raise + seed = b'4' # chosen by a fair dice roll. garanteed to be random + if pycompat.ispy3: + iter_seed = iter(seed) + else: + iter_seed = (ord(c) for c in seed) + # some basic circular sum hashing on 64 bits + int_seed = 0 + low_mask = int('1' * 35, 2) + for i in iter_seed: + high_part = int_seed >> 35 + low_part = (int_seed & low_mask) << 28 + int_seed = high_part + low_part + i + r = random.Random() + if pycompat.ispy3: + r.seed(int_seed, version=1) + else: + r.seed(int_seed) + # once we drop python 3.8 support we can simply use r.randbytes + raw = r.getrandbits(ID_SIZE * 8) + assert ID_SIZE == 8 + p = struct.pack('>Q', raw) + new = hex(p) + with open(stable_docket_file, 'wb') as f: + f.write(new) + return new + + class NodeMapDocket(object): """metadata associated with persistent nodemap data diff --git a/tests/run-tests.py b/tests/run-tests.py --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -1386,6 +1386,8 @@ env['PYTHONUSERBASE'] = sysconfig.get_config_var('userbase') or '' env['HGEMITWARNINGS'] = '1' env['TESTTMP'] = _bytes2sys(self._testtmp) + docket_id_file = os.path.join(_bytes2sys(self._testtmp), 'DOCKETID') + env['HGTEST_DOCKETIDFILE'] = docket_id_file env['TESTNAME'] = self.name env['HOME'] = _bytes2sys(self._testtmp) if os.name == 'nt':