testing interleaved long-running requests in django
I am trying to write tests for django requests which might take a long time to process, and thus might interleave with other requests. My plan was to issue a long-running request, and inject assertions into places where it might suspend.
But trying to use threading in my unit test doesn't seem to work well:
class ThreadTest(test.TestCase):
开发者_开发知识库 def thread_test(self):
def printer():
print models.Daemon.objects.count()
d = models.Daemon(url='http://lockss.notadomain:8088')
d.save()
printer()
t = threading.Thread(target=printer)
t.start()
t.join()
The printer() call works as I'd expect the first time, but then when called from a Thread is unable to find the table:
1
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "/usr/lib/python2.6/threading.py", line 484, in run
self.__target(*self.__args, **self.__kwargs)
File "/home/bhayes/lockss-code/hare/lockss-django/autest/tests.py", line 247, in printer
print models.Daemon.objects.count()
File "/usr/lib/pymodules/python2.6/django/db/models/manager.py", line 120, in count
return self.get_query_set().count()
File "/usr/lib/pymodules/python2.6/django/db/models/query.py", line 326, in count
return self.query.get_count(using=self.db)
File "/usr/lib/pymodules/python2.6/django/db/models/sql/query.py", line 394, in get_count
number = obj.get_aggregation(using=using)[None]
File "/usr/lib/pymodules/python2.6/django/db/models/sql/query.py", line 366, in get_aggregation
result = query.get_compiler(using).execute_sql(SINGLE)
File "/usr/lib/pymodules/python2.6/django/db/models/sql/compiler.py", line 727, in execute_sql
cursor.execute(sql, params)
File "/usr/lib/pymodules/python2.6/django/db/backends/sqlite3/base.py", line 200, in execute
return Database.Cursor.execute(self, query, params)
DatabaseError: no such table: autest_daemon
I'd like to understand what's going on. Also, I'd like to know if there is a better strategy for testing parallel requests.
You can not use threading with in memory databases (sqlite3 in this case) in Django see this bug. Your test would probably work with PostgreSQL or MySQL.
As Rob says, at the time the question was asked, this wasn't possible with SQLite. However, as of Django 1.8 (see https://docs.djangoproject.com/en/1.8/topics/testing/overview/):
If using a SQLite in-memory database with Python 3.4+ and SQLite 3.7.13+, shared cache will be enabled, so you can write tests with ability to share the database between threads.
So if you have the option to upgrade, it should work.
精彩评论