示例#1
0
    def test_release_logs(self, uuid1):
        """
        When lock is released, it logs with time the lock was held
        """
        lock_uuid = 'lock_uuid'
        log = mock.MagicMock(spec=['msg'])
        clock = task.Clock()
        lock = BasicLock(self.client,
                         self.table_name,
                         lock_uuid,
                         max_retry=1,
                         retry_wait=3,
                         reactor=clock,
                         log=log)
        self.responses = [
            None,  # _write_lock
            [{
                'lockId': lock._lock_id,
                'claimId': lock._claim_id
            }],  # _read_lock
            None  # delete for release lock
        ]

        lock.acquire()
        clock.advance(34)
        lock.release()

        log.msg.assert_called_with('Released lock. Was held for 34.0 seconds',
                                   lock_held_time=34.0,
                                   lock_id=lock_uuid,
                                   claim_id='claim_uuid',
                                   result=None)
示例#2
0
    def test_acquire_retry_never_acquired(self):
        """BasicLock.acquire will retry max_retry times and then give up."""
        lock_uuid = uuid.uuid1()

        clock = task.Clock()
        lock = BasicLock(self.client, self.table_name, lock_uuid, max_retry=1, reactor=clock)

        responses = [
            defer.fail(BusyLockError('', '')),
            defer.fail(BusyLockError('', ''))
        ]

        def _new_verify_lock(response):
            return responses.pop(0)
        lock._verify_lock = _new_verify_lock

        def _side_effect(*args, **kwargs):
            return defer.succeed([])
        self.client.execute.side_effect = _side_effect

        d = lock.acquire()

        clock.advance(20)
        result = self.failureResultOf(d)
        self.assertTrue(result.check(BusyLockError))
        self.assertEqual(self.client.execute.call_count, 4)
示例#3
0
    def test_acquire_retry_never_acquired(self):
        """BasicLock.acquire will retry max_retry times and then give up."""
        lock_uuid = uuid.uuid1()

        clock = task.Clock()
        lock = BasicLock(self.client,
                         self.table_name,
                         lock_uuid,
                         max_retry=1,
                         reactor=clock)

        responses = [
            defer.fail(BusyLockError('', '')),
            defer.fail(BusyLockError('', ''))
        ]

        def _new_verify_lock(response):
            return responses.pop(0)

        lock._verify_lock = _new_verify_lock

        def _side_effect(*args, **kwargs):
            return defer.succeed([])

        self.client.execute.side_effect = _side_effect

        d = lock.acquire()

        clock.advance(20)
        result = self.failureResultOf(d)
        self.assertTrue(result.check(BusyLockError))
        self.assertEqual(self.client.execute.call_count, 4)
示例#4
0
    def test_acquire_retry_not_lock_error(self):
        """If an error occurs that is not lock related, it is propagated."""
        lock_uuid = uuid.uuid1()

        clock = task.Clock()
        lock = BasicLock(self.client,
                         self.table_name,
                         lock_uuid,
                         max_retry=1,
                         reactor=clock)

        responses = [
            defer.fail(
                NameError('Keep your foot off the blasted samoflange.')),
        ]

        def _new_verify_lock(response):
            return responses.pop(0)

        lock._verify_lock = _new_verify_lock

        def _side_effect(*args, **kwargs):
            return defer.succeed([])

        self.client.execute.side_effect = _side_effect

        d = lock.acquire()

        result = self.failureResultOf(d)
        self.assertTrue(result.check(NameError))
示例#5
0
    def test_acquire(self):
        """Lock acquire should write and then read back its write."""
        lock_uuid = uuid.uuid1()

        lock = BasicLock(self.client, self.table_name, lock_uuid)

        def _side_effect(*args, **kwargs):
            return defer.succeed([{
                'lockId': lock._lock_id,
                'claimId': lock._claim_id
            }])

        self.client.execute.side_effect = _side_effect

        d = lock.acquire()
        self.assertEqual(self.assertFired(d), True)

        expected = [
            mock.call(
                'INSERT INTO lock ("lockId","claimId") VALUES (:lockId,:claimId) USING TTL 300;',
                {
                    'lockId': lock._lock_id,
                    'claimId': lock._claim_id
                }, 2),
            mock.call(
                'SELECT * FROM lock WHERE "lockId"=:lockId ORDER BY "claimId";',
                {'lockId': lock._lock_id}, 2)
        ]

        self.assertEqual(self.client.execute.call_args_list, expected)
示例#6
0
    def test_acquire_retries_on_NoLockClaimsError(self):
        """
        acquire retries when _verify_lock fails with a NoLockClaimsError.
        """
        lock_uuid = uuid.uuid1()

        clock = task.Clock()
        lock = BasicLock(self.client,
                         self.table_name,
                         lock_uuid,
                         max_retry=1,
                         reactor=clock)

        responses = [
            defer.fail(NoLockClaimsError('', '')),
            defer.succeed(True)
        ]

        def _new_verify_lock(response):
            return responses.pop(0)

        lock._verify_lock = _new_verify_lock

        def _side_effect(*args, **kwargs):
            return defer.succeed([])

        self.client.execute.side_effect = _side_effect

        d = lock.acquire()

        clock.advance(20)
        self.assertEqual(self.assertFired(d), True)
        self.assertEqual(self.client.execute.call_count, 4)
示例#7
0
    def test_lock_acquire_anyfailure_logged(self, uuid1):
        """
        If lock acquisition fails due to any error, it is logged along with time taken
        """
        lock_uuid = 'lock_uuid'
        log = mock.MagicMock(spec=['msg'])
        clock = task.Clock()
        lock = BasicLock(self.client, self.table_name, lock_uuid, max_retry=1,
                         retry_wait=3, reactor=clock, log=log)
        self.responses = [
            None,   # _write_lock
            [{'lockId': lock._lock_id, 'claimId': 'wait for it..'}],  # _read_lock
            None,   # delete for release lock
            None,   # _write_lock again
        ]

        def _execute(*args, **kwargs):
            if not self.responses:
                return defer.fail(ValueError('hmm'))
            return defer.succeed(self.responses.pop(0))

        self.client.execute.side_effect = _execute

        d = lock.acquire()
        clock.advance(3)
        f = self.failureResultOf(d, ValueError)
        log.msg.assert_called_with('Could not acquire lock in 3.0 seconds due to ' + str(f),
                                   lock_acquire_fail_time=3.0, reason=f, lock_id=lock_uuid,
                                   claim_id='claim_uuid')
示例#8
0
    def test_acquire_logs(self, uuid1):
        """
        When lock is acquired, it logs with time taken to acquire the log. Different claim ids
        message is also logged. Intermittent 'release lock' messages are not logged
        """
        lock_uuid = 'lock_uuid'
        log = mock.MagicMock(spec=['msg'])
        clock = task.Clock()
        lock = BasicLock(self.client, self.table_name, lock_uuid, max_retry=1,
                         retry_wait=3, reactor=clock, log=log)
        self.responses = [
            None,   # _write_lock
            [{'lockId': lock._lock_id, 'claimId': 'wait for it..'}],  # _read_lock
            None,   # delete for release lock
            None,   # _write_lock again
            [{'lockId': lock._lock_id, 'claimId': lock._claim_id}]  # _read_lock
        ]

        d = lock.acquire()

        clock.advance(5)
        self.assertEqual(self.assertFired(d), True)
        log.msg.assert_has_calls(
            [mock.call('Got different claimId: wait for it..', diff_claim_id='wait for it..',
                       lock_id=lock_uuid, claim_id='claim_uuid'),
             mock.call('Acquired lock in 5.0 seconds', lock_acquire_time=5.0,
                       lock_id=lock_uuid, claim_id='claim_uuid')])
示例#9
0
    def test_acquire_retries_on_NoLockClaimsError(self):
        """
        acquire retries when _verify_lock fails with a NoLockClaimsError.
        """
        lock_uuid = uuid.uuid1()

        clock = task.Clock()
        lock = BasicLock(self.client, self.table_name, lock_uuid, max_retry=1, reactor=clock)

        responses = [
            defer.fail(NoLockClaimsError('', '')),
            defer.succeed(True)
        ]

        def _new_verify_lock(response):
            return responses.pop(0)
        lock._verify_lock = _new_verify_lock

        def _side_effect(*args, **kwargs):
            return defer.succeed([])
        self.client.execute.side_effect = _side_effect

        d = lock.acquire()

        clock.advance(20)
        self.assertEqual(self.assertFired(d), True)
        self.assertEqual(self.client.execute.call_count, 4)
示例#10
0
    def test_release_logs(self, uuid1):
        """
        When lock is released, it logs with time the lock was held
        """
        lock_uuid = 'lock_uuid'
        log = mock.MagicMock(spec=['msg'])
        clock = task.Clock()
        lock = BasicLock(self.client, self.table_name, lock_uuid, max_retry=1,
                         retry_wait=3, reactor=clock, log=log)
        self.responses = [
            None,   # _write_lock
            [{'lockId': lock._lock_id, 'claimId': lock._claim_id}],  # _read_lock
            None   # delete for release lock
        ]

        lock.acquire()
        clock.advance(34)
        lock.release()

        log.msg.assert_called_with('Released lock. Was held for 34.0 seconds',
                                   lock_held_time=34.0, lock_id=lock_uuid,
                                   claim_id='claim_uuid', result=None)
示例#11
0
    def test_acquire_logs(self, uuid1):
        """
        When lock is acquired, it logs with time taken to acquire the log. Different claim ids
        message is also logged. Intermittent 'release lock' messages are not logged
        """
        lock_uuid = 'lock_uuid'
        log = mock.MagicMock(spec=['msg'])
        clock = task.Clock()
        lock = BasicLock(self.client,
                         self.table_name,
                         lock_uuid,
                         max_retry=1,
                         retry_wait=3,
                         reactor=clock,
                         log=log)
        self.responses = [
            None,  # _write_lock
            [{
                'lockId': lock._lock_id,
                'claimId': 'wait for it..'
            }],  # _read_lock
            None,  # delete for release lock
            None,  # _write_lock again
            [{
                'lockId': lock._lock_id,
                'claimId': lock._claim_id
            }]  # _read_lock
        ]

        d = lock.acquire()

        clock.advance(5)
        self.assertEqual(self.assertFired(d), True)
        log.msg.assert_has_calls([
            mock.call('Got different claimId: wait for it..',
                      diff_claim_id='wait for it..',
                      lock_id=lock_uuid,
                      claim_id='claim_uuid'),
            mock.call('Acquired lock in 5.0 seconds',
                      lock_acquire_time=5.0,
                      lock_id=lock_uuid,
                      claim_id='claim_uuid')
        ])
示例#12
0
    def test_acquire(self):
        """Lock acquire should write and then read back its write."""
        lock_uuid = uuid.uuid1()

        lock = BasicLock(self.client, self.table_name, lock_uuid)

        def _side_effect(*args, **kwargs):
            return defer.succeed([{'lockId': lock._lock_id,
                                   'claimId': lock._claim_id}])
        self.client.execute.side_effect = _side_effect

        d = lock.acquire()
        self.assertEqual(self.assertFired(d), True)

        expected = [
            mock.call('INSERT INTO lock ("lockId","claimId") VALUES (:lockId,:claimId) USING TTL 300;',
                      {'lockId': lock._lock_id, 'claimId': lock._claim_id}, 2),
            mock.call('SELECT * FROM lock WHERE "lockId"=:lockId ORDER BY "claimId";',
                      {'lockId': lock._lock_id}, 2)]

        self.assertEqual(self.client.execute.call_args_list, expected)
示例#13
0
    def test_lock_acquire_anyfailure_logged(self, uuid1):
        """
        If lock acquisition fails due to any error, it is logged along with time taken
        """
        lock_uuid = 'lock_uuid'
        log = mock.MagicMock(spec=['msg'])
        clock = task.Clock()
        lock = BasicLock(self.client,
                         self.table_name,
                         lock_uuid,
                         max_retry=1,
                         retry_wait=3,
                         reactor=clock,
                         log=log)
        self.responses = [
            None,  # _write_lock
            [{
                'lockId': lock._lock_id,
                'claimId': 'wait for it..'
            }],  # _read_lock
            None,  # delete for release lock
            None,  # _write_lock again
        ]

        def _execute(*args, **kwargs):
            if not self.responses:
                return defer.fail(ValueError('hmm'))
            return defer.succeed(self.responses.pop(0))

        self.client.execute.side_effect = _execute

        d = lock.acquire()
        clock.advance(3)
        f = self.failureResultOf(d, ValueError)
        log.msg.assert_called_with(
            'Could not acquire lock in 3.0 seconds due to ' + str(f),
            lock_acquire_fail_time=3.0,
            reason=f,
            lock_id=lock_uuid,
            claim_id='claim_uuid')
示例#14
0
    def test_lock_acquire_failure_logged(self, uuid1):
        """
        If lock acquisition fails due to BusyLockError, it is logged along with time taken
        """
        lock_uuid = 'lock_uuid'
        log = mock.MagicMock(spec=['msg'])
        clock = task.Clock()
        lock = BasicLock(self.client,
                         self.table_name,
                         lock_uuid,
                         max_retry=1,
                         retry_wait=3,
                         reactor=clock,
                         log=log)
        self.responses = [
            None,  # _write_lock
            [{
                'lockId': lock._lock_id,
                'claimId': 'wait for it..'
            }],  # _read_lock
            None,  # delete for release lock
            None,  # _write_lock again
            [{
                'lockId': lock._lock_id,
                'claimId': 'nope'
            }],  # _read_lock
            None  # delete again for release lock
        ]

        d = lock.acquire()
        clock.advance(3)
        f = self.failureResultOf(d, BusyLockError)
        log.msg.assert_called_with(
            'Could not acquire lock in 3.0 seconds due to ' + str(f),
            lock_acquire_fail_time=3.0,
            reason=f,
            lock_id=lock_uuid,
            claim_id='claim_uuid')
示例#15
0
    def test_acquire_retry_not_lock_error(self):
        """If an error occurs that is not lock related, it is propagated."""
        lock_uuid = uuid.uuid1()

        clock = task.Clock()
        lock = BasicLock(self.client, self.table_name, lock_uuid, max_retry=1, reactor=clock)

        responses = [
            defer.fail(NameError('Keep your foot off the blasted samoflange.')),
        ]

        def _new_verify_lock(response):
            return responses.pop(0)
        lock._verify_lock = _new_verify_lock

        def _side_effect(*args, **kwargs):
            return defer.succeed([])
        self.client.execute.side_effect = _side_effect

        d = lock.acquire()

        result = self.failureResultOf(d)
        self.assertTrue(result.check(NameError))
示例#16
0
    def test_lock_acquire_failure_logged(self, uuid1):
        """
        If lock acquisition fails due to BusyLockError, it is logged along with time taken
        """
        lock_uuid = 'lock_uuid'
        log = mock.MagicMock(spec=['msg'])
        clock = task.Clock()
        lock = BasicLock(self.client, self.table_name, lock_uuid, max_retry=1,
                         retry_wait=3, reactor=clock, log=log)
        self.responses = [
            None,   # _write_lock
            [{'lockId': lock._lock_id, 'claimId': 'wait for it..'}],  # _read_lock
            None,   # delete for release lock
            None,   # _write_lock again
            [{'lockId': lock._lock_id, 'claimId': 'nope'}],  # _read_lock
            None   # delete again for release lock
        ]

        d = lock.acquire()
        clock.advance(3)
        f = self.failureResultOf(d, BusyLockError)
        log.msg.assert_called_with('Could not acquire lock in 3.0 seconds due to ' + str(f),
                                   lock_acquire_fail_time=3.0, reason=f, lock_id=lock_uuid,
                                   claim_id='claim_uuid')