Skip to content

Commit

Permalink
Fixed #26933 -- Fixed flaky update_or_create() test from refs #26804.
Browse files Browse the repository at this point in the history
  • Loading branch information
jensen-cochran authored and timgraham committed Jul 29, 2016
1 parent 4178488 commit 83be407
Showing 1 changed file with 18 additions and 5 deletions.
23 changes: 18 additions & 5 deletions tests/get_or_create/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from datetime import date, datetime, timedelta
from threading import Thread

from django.db import DatabaseError, IntegrityError
from django.db import DatabaseError, IntegrityError, connection
from django.test import (
TestCase, TransactionTestCase, ignore_warnings, skipUnlessDBFeature,
)
Expand Down Expand Up @@ -441,14 +441,27 @@ def test_updates_in_transaction(self):
while it holds the lock. The updated field isn't a field in 'defaults',
so update_or_create() shouldn't have an effect on it.
"""
lock_status = {'has_grabbed_lock': False}

def birthday_sleep():
time.sleep(0.3)
lock_status['has_grabbed_lock'] = True
time.sleep(0.5)
return date(1940, 10, 10)

def update_birthday_slowly():
Person.objects.update_or_create(
first_name='John', defaults={'birthday': birthday_sleep}
)
# Avoid leaking connection for Oracle
connection.close()

def lock_wait():
# timeout after ~0.5 seconds
for i in range(20):
time.sleep(0.025)
if lock_status['has_grabbed_lock']:
return True
return False

Person.objects.create(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))

Expand All @@ -457,8 +470,8 @@ def update_birthday_slowly():
before_start = datetime.now()
t.start()

# Wait for lock to begin
time.sleep(0.05)
if not lock_wait():
self.skipTest('Database took too long to lock the row')

# Update during lock
Person.objects.filter(first_name='John').update(last_name='NotLennon')
Expand All @@ -469,5 +482,5 @@ def update_birthday_slowly():

# The update remains and it blocked.
updated_person = Person.objects.get(first_name='John')
self.assertGreater(after_update - before_start, timedelta(seconds=0.3))
self.assertGreater(after_update - before_start, timedelta(seconds=0.5))
self.assertEqual(updated_person.last_name, 'NotLennon')

0 comments on commit 83be407

Please sign in to comment.