tests/test-filecache.py
author Siddharth Agarwal <sid0@fb.com>
Wed, 19 Jun 2013 23:05:40 -0700
branchstable
changeset 19319 ec17ddecdf64
parent 18316 f36375576ed5
child 20040 ed80cecdfc57
permissions -rw-r--r--
test-pathencode: randomize length of each path component This makes it possible for long and short components to exist in the same path. This also makes shorter path components more likely. For randint(1, randint(1, n)), the likelihood that one sees a number k (1 <= k <= n) is 1/n * (\sum_{k=i}^n 1/i). This decreases with k, much like in the real world where shorter paths are more common than longer ones. The previous fix and this one together cause issue3958 to be detected by this test with reasonable frequency. When this test was run 100 times in a loop, the issue was detected 30 of those times.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
     1
import sys, os, subprocess
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
     2
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 15518
diff changeset
     3
if subprocess.call(['python', '%s/hghave' % os.environ['TESTDIR'],
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 15518
diff changeset
     4
                    'cacheable']):
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
     5
    sys.exit(80)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
     6
18313
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
     7
from mercurial import util, scmutil, extensions, hg, ui
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
     8
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
     9
filecache = scmutil.filecache
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    10
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    11
class fakerepo(object):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    12
    def __init__(self):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    13
        self._filecache = {}
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    14
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    15
    def join(self, p):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    16
        return p
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    17
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    18
    def sjoin(self, p):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    19
        return p
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    20
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    21
    @filecache('x')
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    22
    def cached(self):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    23
        print 'creating'
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    24
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    25
    def invalidate(self):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    26
        for k in self._filecache:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    27
            try:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    28
                delattr(self, k)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    29
            except AttributeError:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    30
                pass
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    31
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    32
def basic(repo):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    33
    # file doesn't exist, calls function
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    34
    repo.cached
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    35
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    36
    repo.invalidate()
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    37
    # file still doesn't exist, uses cache
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    38
    repo.cached
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    39
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    40
    # create empty file
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    41
    f = open('x', 'w')
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    42
    f.close()
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    43
    repo.invalidate()
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    44
    # should recreate the object
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    45
    repo.cached
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    46
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    47
    f = open('x', 'w')
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    48
    f.write('a')
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    49
    f.close()
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    50
    repo.invalidate()
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    51
    # should recreate the object
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    52
    repo.cached
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    53
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    54
    repo.invalidate()
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    55
    # stats file again, nothing changed, reuses object
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    56
    repo.cached
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    57
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    58
    # atomic replace file, size doesn't change
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    59
    # hopefully st_mtime doesn't change as well so this doesn't use the cache
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    60
    # because of inode change
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    61
    f = scmutil.opener('.')('x', 'w', atomictemp=True)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    62
    f.write('b')
15057
774da7121fc9 atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents: 14982
diff changeset
    63
    f.close()
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    64
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    65
    repo.invalidate()
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    66
    repo.cached
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    67
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    68
def fakeuncacheable():
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    69
    def wrapcacheable(orig, *args, **kwargs):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    70
        return False
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    71
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    72
    def wrapinit(orig, *args, **kwargs):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    73
        pass
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    74
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    75
    originit = extensions.wrapfunction(util.cachestat, '__init__', wrapinit)
14937
0b3e57c1b8c0 filecache: fix check-code complaint
Matt Mackall <mpm@selenic.com>
parents: 14928
diff changeset
    76
    origcacheable = extensions.wrapfunction(util.cachestat, 'cacheable',
0b3e57c1b8c0 filecache: fix check-code complaint
Matt Mackall <mpm@selenic.com>
parents: 14928
diff changeset
    77
                                            wrapcacheable)
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    78
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    79
    try:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    80
        os.remove('x')
16688
cfb6682961b8 cleanup: replace naked excepts with more specific ones
Brodie Rao <brodie@sf.io>
parents: 16683
diff changeset
    81
    except OSError:
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    82
        pass
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    83
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    84
    basic(fakerepo())
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    85
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    86
    util.cachestat.cacheable = origcacheable
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    87
    util.cachestat.__init__ = originit
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
    88
18313
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
    89
def test_filecache_synced():
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
    90
    # test old behaviour that caused filecached properties to go out of sync
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
    91
    os.system('hg init && echo a >> a && hg ci -qAm.')
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
    92
    repo = hg.repository(ui.ui())
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
    93
    # first rollback clears the filecache, but changelog to stays in __dict__
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
    94
    repo.rollback()
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
    95
    repo.commit('.')
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
    96
    # second rollback comes along and touches the changelog externally
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
    97
    # (file is moved)
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
    98
    repo.rollback()
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
    99
    # but since changelog isn't under the filecache control anymore, we don't
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
   100
    # see that it changed, and return the old changelog without reconstructing
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
   101
    # it
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
   102
    repo.commit('.')
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
   103
18316
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   104
def setbeforeget(repo):
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   105
    os.remove('x')
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   106
    repo.cached = 0
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   107
    repo.invalidate()
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   108
    print repo.cached
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   109
    repo.invalidate()
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   110
    f = open('x', 'w')
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   111
    f.write('a')
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   112
    f.close()
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   113
    print repo.cached
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   114
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
   115
print 'basic:'
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
   116
print
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
   117
basic(fakerepo())
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
   118
print
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
   119
print 'fakeuncacheable:'
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
   120
print
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
   121
fakeuncacheable()
18313
3e4a944c0d04 destroyed: keep the filecache in sync with __dict__ (issue3335) (issue3693) (issue3743)
Idan Kamara <idankk86@gmail.com>
parents: 16688
diff changeset
   122
test_filecache_synced()
18316
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   123
print
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   124
print 'setbeforeget:'
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   125
print
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18313
diff changeset
   126
setbeforeget(fakerepo())