view tests/test-propertycache.py @ 44143:7f86426fdd2c

rust-node: binary Node ID and conversion utilities The choice of type makes sure that a `Node` has the exact wanted size. We'll use a different type for prefixes. Added dependency: hexadecimal conversion relies on the `hex` crate. The fact that sooner or later Mercurial is going to need to change its hash sizes has been taken strongly in consideration: - the hash length is a constant, but that is not directly exposed to callers. Changing the value of that constant is the only thing to do to change the hash length (even in unit tests) - the code could be adapted to support several sizes of hashes, if that turned out to be useful. To that effect, only the size of a given `Node` is exposed in the public API. - callers not involved in initial computation, I/O and FFI are able to operate without a priori assumptions on the hash size. The traits `FromHex` and `ToHex` have not been directly implemented, so that the doc-comments explaining these restrictions would stay really visible in `cargo doc` Differential Revision: https://phab.mercurial-scm.org/D7788
author Georges Racinet <georges.racinet@octobus.net>
date Wed, 22 Jan 2020 16:37:05 +0100
parents 2372284d9457
children 6000f5b25c9b
line wrap: on
line source

"""test behavior of propertycache and unfiltered propertycache

The repoview overlay is quite complex. We test the behavior of
property cache of both localrepo and repoview to prevent
regression."""

from __future__ import absolute_import, print_function
import os
import subprocess

from mercurial import (
    hg,
    localrepo,
    pycompat,
    ui as uimod,
    util,
)

from mercurial.utils import procutil

# create some special property cache that trace they call

calllog = []


@util.propertycache
def testcachedfoobar(repo):
    name = repo.filtername
    if name is None:
        name = ''
    val = len(name)
    calllog.append(val)
    return val


unficalllog = []


@localrepo.unfilteredpropertycache
def testcachedunfifoobar(repo):
    name = repo.filtername
    if name is None:
        name = ''
    val = 100 + len(name)
    unficalllog.append(val)
    return val


# plug them on repo
localrepo.localrepository.testcachedfoobar = testcachedfoobar
localrepo.localrepository.testcachedunfifoobar = testcachedunfifoobar


# Create an empty repo and instantiate it. It is important to run
# these tests on the real object to detect regression.
repopath = pycompat.fsencode(os.path.join(os.environ['TESTTMP'], 'repo'))
assert (
    subprocess.call(
        pycompat.rapply(procutil.tonativestr, [b'hg', b'init', repopath])
    )
    == 0
)

ui = uimod.ui.load()
repo = hg.repository(ui, path=repopath).unfiltered()


print('')
print('=== property cache ===')
print('')
print('calllog:', calllog)
print(
    'cached value (unfiltered):', vars(repo).get('testcachedfoobar', 'NOCACHE')
)

print('')
print('= first access on unfiltered, should do a call')
print('access:', repo.testcachedfoobar)
print('calllog:', calllog)
print(
    'cached value (unfiltered):', vars(repo).get('testcachedfoobar', 'NOCACHE')
)

print('')
print('= second access on unfiltered, should not do call')
print('access', repo.testcachedfoobar)
print('calllog:', calllog)
print(
    'cached value (unfiltered):', vars(repo).get('testcachedfoobar', 'NOCACHE')
)

print('')
print('= first access on "visible" view, should do a call')
visibleview = repo.filtered('visible')
print(
    'cached value ("visible" view):',
    vars(visibleview).get('testcachedfoobar', 'NOCACHE'),
)
print('access:', visibleview.testcachedfoobar)
print('calllog:', calllog)
print(
    'cached value (unfiltered):', vars(repo).get('testcachedfoobar', 'NOCACHE')
)
print(
    'cached value ("visible" view):',
    vars(visibleview).get('testcachedfoobar', 'NOCACHE'),
)

print('')
print('= second access on "visible view", should not do call')
print('access:', visibleview.testcachedfoobar)
print('calllog:', calllog)
print(
    'cached value (unfiltered):', vars(repo).get('testcachedfoobar', 'NOCACHE')
)
print(
    'cached value ("visible" view):',
    vars(visibleview).get('testcachedfoobar', 'NOCACHE'),
)

print('')
print('= no effect on other view')
immutableview = repo.filtered('immutable')
print(
    'cached value ("immutable" view):',
    vars(immutableview).get('testcachedfoobar', 'NOCACHE'),
)
print('access:', immutableview.testcachedfoobar)
print('calllog:', calllog)
print(
    'cached value (unfiltered):', vars(repo).get('testcachedfoobar', 'NOCACHE')
)
print(
    'cached value ("visible" view):',
    vars(visibleview).get('testcachedfoobar', 'NOCACHE'),
)
print(
    'cached value ("immutable" view):',
    vars(immutableview).get('testcachedfoobar', 'NOCACHE'),
)

# unfiltered property cache test
print('')
print('')
print('=== unfiltered property cache ===')
print('')
print('unficalllog:', unficalllog)
print(
    'cached value (unfiltered):      ',
    vars(repo).get('testcachedunfifoobar', 'NOCACHE'),
)
print(
    'cached value ("visible" view):  ',
    vars(visibleview).get('testcachedunfifoobar', 'NOCACHE'),
)
print(
    'cached value ("immutable" view):',
    vars(immutableview).get('testcachedunfifoobar', 'NOCACHE'),
)

print('')
print('= first access on unfiltered, should do a call')
print('access (unfiltered):', repo.testcachedunfifoobar)
print('unficalllog:', unficalllog)
print(
    'cached value (unfiltered):      ',
    vars(repo).get('testcachedunfifoobar', 'NOCACHE'),
)

print('')
print('= second access on unfiltered, should not do call')
print('access (unfiltered):', repo.testcachedunfifoobar)
print('unficalllog:', unficalllog)
print(
    'cached value (unfiltered):      ',
    vars(repo).get('testcachedunfifoobar', 'NOCACHE'),
)

print('')
print('= access on view should use the unfiltered cache')
print('access (unfiltered):      ', repo.testcachedunfifoobar)
print('access ("visible" view):  ', visibleview.testcachedunfifoobar)
print('access ("immutable" view):', immutableview.testcachedunfifoobar)
print('unficalllog:', unficalllog)
print(
    'cached value (unfiltered):      ',
    vars(repo).get('testcachedunfifoobar', 'NOCACHE'),
)
print(
    'cached value ("visible" view):  ',
    vars(visibleview).get('testcachedunfifoobar', 'NOCACHE'),
)
print(
    'cached value ("immutable" view):',
    vars(immutableview).get('testcachedunfifoobar', 'NOCACHE'),
)

print('')
print('= even if we clear the unfiltered cache')
del repo.__dict__['testcachedunfifoobar']
print(
    'cached value (unfiltered):      ',
    vars(repo).get('testcachedunfifoobar', 'NOCACHE'),
)
print(
    'cached value ("visible" view):  ',
    vars(visibleview).get('testcachedunfifoobar', 'NOCACHE'),
)
print(
    'cached value ("immutable" view):',
    vars(immutableview).get('testcachedunfifoobar', 'NOCACHE'),
)
print('unficalllog:', unficalllog)
print('access ("visible" view):  ', visibleview.testcachedunfifoobar)
print('unficalllog:', unficalllog)
print(
    'cached value (unfiltered):      ',
    vars(repo).get('testcachedunfifoobar', 'NOCACHE'),
)
print(
    'cached value ("visible" view):  ',
    vars(visibleview).get('testcachedunfifoobar', 'NOCACHE'),
)
print(
    'cached value ("immutable" view):',
    vars(immutableview).get('testcachedunfifoobar', 'NOCACHE'),
)
print('access ("immutable" view):', immutableview.testcachedunfifoobar)
print('unficalllog:', unficalllog)
print(
    'cached value (unfiltered):      ',
    vars(repo).get('testcachedunfifoobar', 'NOCACHE'),
)
print(
    'cached value ("visible" view):  ',
    vars(visibleview).get('testcachedunfifoobar', 'NOCACHE'),
)
print(
    'cached value ("immutable" view):',
    vars(immutableview).get('testcachedunfifoobar', 'NOCACHE'),
)
print('access (unfiltered):      ', repo.testcachedunfifoobar)
print('unficalllog:', unficalllog)
print(
    'cached value (unfiltered):      ',
    vars(repo).get('testcachedunfifoobar', 'NOCACHE'),
)
print(
    'cached value ("visible" view):  ',
    vars(visibleview).get('testcachedunfifoobar', 'NOCACHE'),
)
print(
    'cached value ("immutable" view):',
    vars(immutableview).get('testcachedunfifoobar', 'NOCACHE'),
)