tests/test-lock.py
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
Fri, 31 Mar 2017 11:06:42 +0200
changeset 31745 33504b54863e
parent 31249 e067741d4607
child 32088 0d892d820a51
permissions -rw-r--r--
hook: use 'htype' in 'hook' Same rational as for 'runhooks', we fix the naming in another function.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     1
from __future__ import absolute_import
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     2
26386
146cccdb282b test-lock.py: fix testing for forks
Siddharth Agarwal <sid0@fb.com>
parents: 26385
diff changeset
     3
import copy
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     4
import os
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     5
import silenttestrunner
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     6
import tempfile
26386
146cccdb282b test-lock.py: fix testing for forks
Siddharth Agarwal <sid0@fb.com>
parents: 26385
diff changeset
     7
import types
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     8
import unittest
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     9
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    10
from mercurial import (
26498
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
    11
    error,
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    12
    lock,
31249
e067741d4607 vfs: use 'vfs' module directly in 'test-lock'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28027
diff changeset
    13
    vfs as vfsmod,
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    14
)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    15
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    16
testlockname = 'testlock'
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    17
26386
146cccdb282b test-lock.py: fix testing for forks
Siddharth Agarwal <sid0@fb.com>
parents: 26385
diff changeset
    18
# work around http://bugs.python.org/issue1515
146cccdb282b test-lock.py: fix testing for forks
Siddharth Agarwal <sid0@fb.com>
parents: 26385
diff changeset
    19
if types.MethodType not in copy._deepcopy_dispatch:
146cccdb282b test-lock.py: fix testing for forks
Siddharth Agarwal <sid0@fb.com>
parents: 26385
diff changeset
    20
    def _deepcopy_method(x, memo):
146cccdb282b test-lock.py: fix testing for forks
Siddharth Agarwal <sid0@fb.com>
parents: 26385
diff changeset
    21
        return type(x)(x.im_func, copy.deepcopy(x.im_self, memo), x.im_class)
146cccdb282b test-lock.py: fix testing for forks
Siddharth Agarwal <sid0@fb.com>
parents: 26385
diff changeset
    22
    copy._deepcopy_dispatch[types.MethodType] = _deepcopy_method
146cccdb282b test-lock.py: fix testing for forks
Siddharth Agarwal <sid0@fb.com>
parents: 26385
diff changeset
    23
26384
ad6e56d01c30 test-lock.py: add a lock wrapper that allows faking the PID
Siddharth Agarwal <sid0@fb.com>
parents: 26382
diff changeset
    24
class lockwrapper(lock.lock):
ad6e56d01c30 test-lock.py: add a lock wrapper that allows faking the PID
Siddharth Agarwal <sid0@fb.com>
parents: 26382
diff changeset
    25
    def __init__(self, pidoffset, *args, **kwargs):
ad6e56d01c30 test-lock.py: add a lock wrapper that allows faking the PID
Siddharth Agarwal <sid0@fb.com>
parents: 26382
diff changeset
    26
        # lock.lock.__init__() calls lock(), so the pidoffset assignment needs
ad6e56d01c30 test-lock.py: add a lock wrapper that allows faking the PID
Siddharth Agarwal <sid0@fb.com>
parents: 26382
diff changeset
    27
        # to be earlier
ad6e56d01c30 test-lock.py: add a lock wrapper that allows faking the PID
Siddharth Agarwal <sid0@fb.com>
parents: 26382
diff changeset
    28
        self._pidoffset = pidoffset
ad6e56d01c30 test-lock.py: add a lock wrapper that allows faking the PID
Siddharth Agarwal <sid0@fb.com>
parents: 26382
diff changeset
    29
        super(lockwrapper, self).__init__(*args, **kwargs)
ad6e56d01c30 test-lock.py: add a lock wrapper that allows faking the PID
Siddharth Agarwal <sid0@fb.com>
parents: 26382
diff changeset
    30
    def _getpid(self):
28027
14033c5dd261 util: enable getpid to be replaced
timeless <timeless@mozdev.org>
parents: 26499
diff changeset
    31
        return super(lockwrapper, self)._getpid() + self._pidoffset
26384
ad6e56d01c30 test-lock.py: add a lock wrapper that allows faking the PID
Siddharth Agarwal <sid0@fb.com>
parents: 26382
diff changeset
    32
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    33
class teststate(object):
26385
fb1a424e8bff test-lock.py: allow PID to be changed in test state
Siddharth Agarwal <sid0@fb.com>
parents: 26384
diff changeset
    34
    def __init__(self, testcase, dir, pidoffset=0):
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    35
        self._testcase = testcase
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    36
        self._acquirecalled = False
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    37
        self._releasecalled = False
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    38
        self._postreleasecalled = False
31249
e067741d4607 vfs: use 'vfs' module directly in 'test-lock'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28027
diff changeset
    39
        self.vfs = vfsmod.vfs(dir, audit=False)
26385
fb1a424e8bff test-lock.py: allow PID to be changed in test state
Siddharth Agarwal <sid0@fb.com>
parents: 26384
diff changeset
    40
        self._pidoffset = pidoffset
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    41
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    42
    def makelock(self, *args, **kwargs):
26385
fb1a424e8bff test-lock.py: allow PID to be changed in test state
Siddharth Agarwal <sid0@fb.com>
parents: 26384
diff changeset
    43
        l = lockwrapper(self._pidoffset, self.vfs, testlockname,
fb1a424e8bff test-lock.py: allow PID to be changed in test state
Siddharth Agarwal <sid0@fb.com>
parents: 26384
diff changeset
    44
                        releasefn=self.releasefn, acquirefn=self.acquirefn,
fb1a424e8bff test-lock.py: allow PID to be changed in test state
Siddharth Agarwal <sid0@fb.com>
parents: 26384
diff changeset
    45
                        *args, **kwargs)
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    46
        l.postrelease.append(self.postreleasefn)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    47
        return l
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    48
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    49
    def acquirefn(self):
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    50
        self._acquirecalled = True
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    51
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    52
    def releasefn(self):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    53
        self._releasecalled = True
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    54
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    55
    def postreleasefn(self):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    56
        self._postreleasecalled = True
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    57
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    58
    def assertacquirecalled(self, called):
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    59
        self._testcase.assertEqual(
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    60
            self._acquirecalled, called,
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    61
            'expected acquire to be %s but was actually %s' % (
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    62
                self._tocalled(called),
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    63
                self._tocalled(self._acquirecalled),
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    64
            ))
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    65
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    66
    def resetacquirefn(self):
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    67
        self._acquirecalled = False
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
    68
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    69
    def assertreleasecalled(self, called):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    70
        self._testcase.assertEqual(
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    71
            self._releasecalled, called,
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    72
            'expected release to be %s but was actually %s' % (
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    73
                self._tocalled(called),
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    74
                self._tocalled(self._releasecalled),
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    75
            ))
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    76
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    77
    def assertpostreleasecalled(self, called):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    78
        self._testcase.assertEqual(
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    79
            self._postreleasecalled, called,
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    80
            'expected postrelease to be %s but was actually %s' % (
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    81
                self._tocalled(called),
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    82
                self._tocalled(self._postreleasecalled),
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    83
            ))
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    84
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    85
    def assertlockexists(self, exists):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    86
        actual = self.vfs.lexists(testlockname)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    87
        self._testcase.assertEqual(
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    88
            actual, exists,
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    89
            'expected lock to %s but actually did %s' % (
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    90
                self._toexists(exists),
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    91
                self._toexists(actual),
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    92
            ))
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    93
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    94
    def _tocalled(self, called):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    95
        if called:
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    96
            return 'called'
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    97
        else:
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    98
            return 'not called'
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    99
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   100
    def _toexists(self, exists):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   101
        if exists:
26381
94dc10834b79 test-lock.py: copy-edit assertions about file existing
Siddharth Agarwal <sid0@fb.com>
parents: 26321
diff changeset
   102
            return 'exist'
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   103
        else:
26381
94dc10834b79 test-lock.py: copy-edit assertions about file existing
Siddharth Agarwal <sid0@fb.com>
parents: 26321
diff changeset
   104
            return 'not exist'
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   105
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   106
class testlock(unittest.TestCase):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   107
    def testlock(self):
26382
b673e89affc9 test-lock.py: move temp dir generation to testcase
Siddharth Agarwal <sid0@fb.com>
parents: 26381
diff changeset
   108
        state = teststate(self, tempfile.mkdtemp(dir=os.getcwd()))
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   109
        lock = state.makelock()
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
   110
        state.assertacquirecalled(True)
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   111
        lock.release()
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   112
        state.assertreleasecalled(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   113
        state.assertpostreleasecalled(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   114
        state.assertlockexists(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   115
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   116
    def testrecursivelock(self):
26382
b673e89affc9 test-lock.py: move temp dir generation to testcase
Siddharth Agarwal <sid0@fb.com>
parents: 26381
diff changeset
   117
        state = teststate(self, tempfile.mkdtemp(dir=os.getcwd()))
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   118
        lock = state.makelock()
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
   119
        state.assertacquirecalled(True)
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
   120
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
   121
        state.resetacquirefn()
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   122
        lock.lock()
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
   123
        # recursive lock should not call acquirefn again
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
   124
        state.assertacquirecalled(False)
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
   125
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   126
        lock.release() # brings lock refcount down from 2 to 1
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   127
        state.assertreleasecalled(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   128
        state.assertpostreleasecalled(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   129
        state.assertlockexists(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   130
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   131
        lock.release() # releases the lock
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   132
        state.assertreleasecalled(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   133
        state.assertpostreleasecalled(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   134
        state.assertlockexists(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   135
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   136
    def testlockfork(self):
26382
b673e89affc9 test-lock.py: move temp dir generation to testcase
Siddharth Agarwal <sid0@fb.com>
parents: 26381
diff changeset
   137
        state = teststate(self, tempfile.mkdtemp(dir=os.getcwd()))
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   138
        lock = state.makelock()
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
   139
        state.assertacquirecalled(True)
26386
146cccdb282b test-lock.py: fix testing for forks
Siddharth Agarwal <sid0@fb.com>
parents: 26385
diff changeset
   140
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   141
        # fake a fork
26386
146cccdb282b test-lock.py: fix testing for forks
Siddharth Agarwal <sid0@fb.com>
parents: 26385
diff changeset
   142
        forklock = copy.deepcopy(lock)
146cccdb282b test-lock.py: fix testing for forks
Siddharth Agarwal <sid0@fb.com>
parents: 26385
diff changeset
   143
        forklock._pidoffset = 1
146cccdb282b test-lock.py: fix testing for forks
Siddharth Agarwal <sid0@fb.com>
parents: 26385
diff changeset
   144
        forklock.release()
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   145
        state.assertreleasecalled(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   146
        state.assertpostreleasecalled(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   147
        state.assertlockexists(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   148
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   149
        # release the actual lock
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   150
        lock.release()
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   151
        state.assertreleasecalled(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   152
        state.assertpostreleasecalled(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   153
        state.assertlockexists(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   154
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   155
    def testinheritlock(self):
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   156
        d = tempfile.mkdtemp(dir=os.getcwd())
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   157
        parentstate = teststate(self, d)
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   158
        parentlock = parentstate.makelock()
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   159
        parentstate.assertacquirecalled(True)
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   160
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   161
        # set up lock inheritance
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   162
        with parentlock.inherit() as lockname:
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   163
            parentstate.assertreleasecalled(True)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   164
            parentstate.assertpostreleasecalled(False)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   165
            parentstate.assertlockexists(True)
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   166
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   167
            childstate = teststate(self, d, pidoffset=1)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   168
            childlock = childstate.makelock(parentlock=lockname)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   169
            childstate.assertacquirecalled(True)
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   170
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   171
            childlock.release()
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   172
            childstate.assertreleasecalled(True)
26474
431094a3b21f lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26473
diff changeset
   173
            childstate.assertpostreleasecalled(False)
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   174
            childstate.assertlockexists(True)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   175
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   176
            parentstate.resetacquirefn()
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   177
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   178
        parentstate.assertacquirecalled(True)
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   179
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   180
        parentlock.release()
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   181
        parentstate.assertreleasecalled(True)
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   182
        parentstate.assertpostreleasecalled(True)
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   183
        parentstate.assertlockexists(False)
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   184
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   185
    def testmultilock(self):
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   186
        d = tempfile.mkdtemp(dir=os.getcwd())
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   187
        state0 = teststate(self, d)
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   188
        lock0 = state0.makelock()
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   189
        state0.assertacquirecalled(True)
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   190
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   191
        with lock0.inherit() as lock0name:
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   192
            state0.assertreleasecalled(True)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   193
            state0.assertpostreleasecalled(False)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   194
            state0.assertlockexists(True)
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   195
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   196
            state1 = teststate(self, d, pidoffset=1)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   197
            lock1 = state1.makelock(parentlock=lock0name)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   198
            state1.assertacquirecalled(True)
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   199
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   200
            # from within lock1, acquire another lock
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   201
            with lock1.inherit() as lock1name:
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   202
                # since the file on disk is lock0's this should have the same
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   203
                # name
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   204
                self.assertEqual(lock0name, lock1name)
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   205
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   206
                state2 = teststate(self, d, pidoffset=2)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   207
                lock2 = state2.makelock(parentlock=lock1name)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   208
                state2.assertacquirecalled(True)
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   209
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   210
                lock2.release()
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   211
                state2.assertreleasecalled(True)
26474
431094a3b21f lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26473
diff changeset
   212
                state2.assertpostreleasecalled(False)
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   213
                state2.assertlockexists(True)
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   214
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   215
                state1.resetacquirefn()
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   216
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   217
            state1.assertacquirecalled(True)
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   218
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   219
            lock1.release()
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   220
            state1.assertreleasecalled(True)
26474
431094a3b21f lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26473
diff changeset
   221
            state1.assertpostreleasecalled(False)
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   222
            state1.assertlockexists(True)
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   223
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   224
        lock0.release()
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   225
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   226
    def testinheritlockfork(self):
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   227
        d = tempfile.mkdtemp(dir=os.getcwd())
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   228
        parentstate = teststate(self, d)
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   229
        parentlock = parentstate.makelock()
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   230
        parentstate.assertacquirecalled(True)
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   231
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   232
        # set up lock inheritance
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   233
        with parentlock.inherit() as lockname:
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   234
            childstate = teststate(self, d, pidoffset=1)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   235
            childlock = childstate.makelock(parentlock=lockname)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   236
            childstate.assertacquirecalled(True)
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   237
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   238
            # fork the child lock
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   239
            forkchildlock = copy.deepcopy(childlock)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   240
            forkchildlock._pidoffset += 1
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   241
            forkchildlock.release()
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   242
            childstate.assertreleasecalled(False)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   243
            childstate.assertpostreleasecalled(False)
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   244
            childstate.assertlockexists(True)
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   245
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   246
            # release the child lock
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   247
            childlock.release()
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   248
            childstate.assertreleasecalled(True)
26474
431094a3b21f lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26473
diff changeset
   249
            childstate.assertpostreleasecalled(False)
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   250
            childstate.assertlockexists(True)
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   251
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   252
        parentlock.release()
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26386
diff changeset
   253
26498
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   254
    def testinheritcheck(self):
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   255
        d = tempfile.mkdtemp(dir=os.getcwd())
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   256
        state = teststate(self, d)
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   257
        def check():
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   258
            raise error.LockInheritanceContractViolation('check failed')
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   259
        lock = state.makelock(inheritchecker=check)
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   260
        state.assertacquirecalled(True)
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   261
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   262
        def tryinherit():
26499
e72b62b154b0 localrepo: prevent wlock from being inherited when a transaction is running
Siddharth Agarwal <sid0@fb.com>
parents: 26498
diff changeset
   263
            with lock.inherit():
26498
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   264
                pass
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   265
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   266
        self.assertRaises(error.LockInheritanceContractViolation, tryinherit)
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   267
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   268
        lock.release()
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   269
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   270
if __name__ == '__main__':
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   271
    silenttestrunner.main(__name__)