ut: Patch get_ident for race transaction test

In case eventlet is installed on the system, the time.sleep() function
doesn't yield.  This patch replaces time.sleep with eventlet.sleep and
thread.get_ident functions on systems with eventlet installed. With this
patch, a concurrent transaction test can be executed both with and
without eventlet successfuly.

Change-Id: I4572355d7d420111e562d4d1f4ea3dd95d4e3f7d
Related-bug: #1793499
This commit is contained in:
Jakub Libosvar 2018-09-21 11:19:12 +00:00
parent 19be7612e7
commit 64342ba52c
1 changed files with 24 additions and 4 deletions

View File

@ -12,27 +12,46 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import sys
import fixtures
import mock import mock
import testtools import testtools
import time
from ovsdbapp import api from ovsdbapp import api
from ovsdbapp.tests import base from ovsdbapp.tests import base
try: try:
import eventlet import eventlet
from eventlet.green import thread
sleep = eventlet.sleep
def create_thread(executable): def create_thread(executable):
eventlet.spawn_n(executable) eventlet.spawn_n(executable)
except ImportError: except ImportError:
import threading import threading
import time
sleep = time.sleep
def create_thread(executable): def create_thread(executable):
thread = threading.Thread(target=executable) thread = threading.Thread(target=executable)
thread.start() thread.start()
class GreenThreadingFixture(fixtures.Fixture):
def _setUp(self):
if 'eventlet' in sys.modules:
self._orig = api.thread.get_ident
api.thread.get_ident = thread.get_ident
self.addCleanup(self.cleanup)
def cleanup(self):
api.thread.get_ident = self._orig
class FakeTransaction(object): class FakeTransaction(object):
def __enter__(self): def __enter__(self):
return self return self
@ -57,6 +76,7 @@ class TransactionTestCase(base.TestCase):
super(TransactionTestCase, self).setUp() super(TransactionTestCase, self).setUp()
self.api = TestingAPI() self.api = TestingAPI()
mock.patch.object(FakeTransaction, 'commit').start() mock.patch.object(FakeTransaction, 'commit').start()
self.useFixture(GreenThreadingFixture())
def test_transaction_nested(self): def test_transaction_nested(self):
with self.api.transaction() as txn1: with self.api.transaction() as txn1:
@ -82,12 +102,12 @@ class TransactionTestCase(base.TestCase):
with self.api.transaction() as txn: with self.api.transaction() as txn:
shared_resource.append(txn) shared_resource.append(txn)
while len(shared_resource) == 1: while len(shared_resource) == 1:
time.sleep(0.1) sleep(0.1)
shared_resource.append(0) shared_resource.append(0)
def thread2(): def thread2():
while len(shared_resource) != 1: while len(shared_resource) != 1:
time.sleep(0.1) sleep(0.1)
with self.api.transaction() as txn: with self.api.transaction() as txn:
shared_resource.append(txn) shared_resource.append(txn)
shared_resource.append(0) shared_resource.append(0)
@ -96,7 +116,7 @@ class TransactionTestCase(base.TestCase):
create_thread(thread2) create_thread(thread2)
while len(shared_resource) != 4: while len(shared_resource) != 4:
time.sleep(0.1) sleep(0.1)
txn1, txn2 = shared_resource[:2] txn1, txn2 = shared_resource[:2]