Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlogutils/nodemap.py @ 47321:9a3aa54774ff
persistent-nodemap: add a way to make the picked uid predictable
This will make the test less volatile and therefore easier to maintain. I am
setting this is for the persistent nodemap docket first, but my target is to use
similar logic for the revlogv2 (and co) test.
For persisent nodemap, they are too many different in how each test variants (with rust, without rust, etc) needs new uid for this be really useful (right now). However it will be directly useful for the revlogv2 logic.
Differential Revision: https://phab.mercurial-scm.org/D10753
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Wed, 19 May 2021 17:19:46 +0200 |
parents | 4f38ada3fc26 |
children | 5bc6d2fc1cfc |
comparison
equal
deleted
inserted
replaced
47320:af4d1a177548 | 47321:9a3aa54774ff |
---|---|
8 | 8 |
9 from __future__ import absolute_import | 9 from __future__ import absolute_import |
10 | 10 |
11 import errno | 11 import errno |
12 import os | 12 import os |
13 import random | |
13 import re | 14 import re |
14 import struct | 15 import struct |
15 | 16 |
16 from ..node import hex | 17 from ..node import hex |
17 | 18 |
18 from .. import ( | 19 from .. import ( |
20 encoding, | |
19 error, | 21 error, |
22 pycompat, | |
20 util, | 23 util, |
21 ) | 24 ) |
22 | 25 |
23 | 26 |
24 class NodeMap(dict): | 27 class NodeMap(dict): |
284 def _make_uid(): | 287 def _make_uid(): |
285 """return a new unique identifier. | 288 """return a new unique identifier. |
286 | 289 |
287 The identifier is random and composed of ascii characters.""" | 290 The identifier is random and composed of ascii characters.""" |
288 return hex(os.urandom(ID_SIZE)) | 291 return hex(os.urandom(ID_SIZE)) |
292 | |
293 | |
294 # some special test logic to avoid anoying random output in the test | |
295 stable_docket_file = encoding.environ.get(b'HGTEST_DOCKETIDFILE') | |
296 | |
297 if stable_docket_file: | |
298 | |
299 def _make_uid(): | |
300 try: | |
301 with open(stable_docket_file, mode='rb') as f: | |
302 seed = f.read().strip() | |
303 except IOError as inst: | |
304 if inst.errno != errno.ENOENT: | |
305 raise | |
306 seed = b'4' # chosen by a fair dice roll. garanteed to be random | |
307 if pycompat.ispy3: | |
308 iter_seed = iter(seed) | |
309 else: | |
310 iter_seed = (ord(c) for c in seed) | |
311 # some basic circular sum hashing on 64 bits | |
312 int_seed = 0 | |
313 low_mask = int('1' * 35, 2) | |
314 for i in iter_seed: | |
315 high_part = int_seed >> 35 | |
316 low_part = (int_seed & low_mask) << 28 | |
317 int_seed = high_part + low_part + i | |
318 r = random.Random() | |
319 if pycompat.ispy3: | |
320 r.seed(int_seed, version=1) | |
321 else: | |
322 r.seed(int_seed) | |
323 # once we drop python 3.8 support we can simply use r.randbytes | |
324 raw = r.getrandbits(ID_SIZE * 8) | |
325 assert ID_SIZE == 8 | |
326 p = struct.pack('>Q', raw) | |
327 new = hex(p) | |
328 with open(stable_docket_file, 'wb') as f: | |
329 f.write(new) | |
330 return new | |
289 | 331 |
290 | 332 |
291 class NodeMapDocket(object): | 333 class NodeMapDocket(object): |
292 """metadata associated with persistent nodemap data | 334 """metadata associated with persistent nodemap data |
293 | 335 |