odoo/ext/3rd-party-addons/connector/tests/test_advisory_lock.py

76 lines
2.8 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2017 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
import mock
from odoo import api
from odoo.tests import common
from odoo.modules.registry import Registry
from odoo.addons.queue_job.exception import RetryableJobError
from odoo.addons.connector.database import pg_try_advisory_lock
from odoo.addons.component.core import WorkContext
from odoo.addons.component.tests.common import TransactionComponentCase
class TestAdvisoryLock(TransactionComponentCase):
def setUp(self):
super(TestAdvisoryLock, self).setUp()
self.registry2 = Registry(common.get_db_name())
self.cr2 = self.registry2.cursor()
self.env2 = api.Environment(self.cr2, self.env.uid, {})
@self.addCleanup
def reset_cr2():
# rollback and close the cursor, and reset the environments
self.env2.reset()
self.cr2.rollback()
self.cr2.close()
def test_concurrent_lock(self):
""" 2 concurrent transactions cannot acquire the same lock """
# the lock is based on a string, a second transaction trying
# to acquire the same lock won't be able to acquire it
lock = 'import_record({}, {}, {}, {})'.format(
'backend.name',
1,
'res.partner',
'999999',
)
acquired = pg_try_advisory_lock(self.env, lock)
self.assertTrue(acquired)
# we test the base function
inner_acquired = pg_try_advisory_lock(self.env2, lock)
self.assertFalse(inner_acquired)
def test_concurrent_import_lock(self):
""" A 2nd concurrent transaction must retry """
# the lock is based on a string, a second transaction trying
# to acquire the same lock won't be able to acquire it
lock = 'import_record({}, {}, {}, {})'.format(
'backend.name',
1,
'res.partner',
'999999',
)
backend = mock.MagicMock()
backend.env = self.env
work = WorkContext(model_name='res.partner',
collection=backend)
# we test the function through a Component instance
component = work.component_by_name('base.connector')
# acquire the lock
component.advisory_lock_or_retry(lock)
# instanciate another component using a different odoo env
# hence another PG transaction
backend2 = mock.MagicMock()
backend2.env = self.env2
work2 = WorkContext(model_name='res.partner',
collection=backend2)
component2 = work2.component_by_name('base.connector')
with self.assertRaises(RetryableJobError) as cm:
component2.advisory_lock_or_retry(lock, retry_seconds=3)
self.assertEqual(cm.exception.seconds, 3)