tests.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import re
  2. import threading
  3. import unittest
  4. from django.db import connection
  5. from django.db.models import Avg, StdDev, Sum, Variance
  6. from django.db.utils import NotSupportedError
  7. from django.test import TestCase, TransactionTestCase, override_settings
  8. from ..models import Item, Object, Square
  9. @unittest.skipUnless(connection.vendor == 'sqlite', 'SQLite tests')
  10. class Tests(TestCase):
  11. longMessage = True
  12. def test_autoincrement(self):
  13. """
  14. auto_increment fields are created with the AUTOINCREMENT keyword
  15. in order to be monotonically increasing (#10164).
  16. """
  17. with connection.schema_editor(collect_sql=True) as editor:
  18. editor.create_model(Square)
  19. statements = editor.collected_sql
  20. match = re.search('"id" ([^,]+),', statements[0])
  21. self.assertIsNotNone(match)
  22. self.assertEqual(
  23. 'integer NOT NULL PRIMARY KEY AUTOINCREMENT',
  24. match.group(1),
  25. 'Wrong SQL used to create an auto-increment column on SQLite'
  26. )
  27. def test_aggregation(self):
  28. """
  29. Raise NotImplementedError when aggregating on date/time fields (#19360).
  30. """
  31. for aggregate in (Sum, Avg, Variance, StdDev):
  32. with self.assertRaises(NotSupportedError):
  33. Item.objects.all().aggregate(aggregate('time'))
  34. with self.assertRaises(NotSupportedError):
  35. Item.objects.all().aggregate(aggregate('date'))
  36. with self.assertRaises(NotSupportedError):
  37. Item.objects.all().aggregate(aggregate('last_modified'))
  38. with self.assertRaises(NotSupportedError):
  39. Item.objects.all().aggregate(
  40. **{'complex': aggregate('last_modified') + aggregate('last_modified')}
  41. )
  42. def test_memory_db_test_name(self):
  43. """A named in-memory db should be allowed where supported."""
  44. from django.db.backends.sqlite3.base import DatabaseWrapper
  45. settings_dict = {
  46. 'TEST': {
  47. 'NAME': 'file:memorydb_test?mode=memory&cache=shared',
  48. }
  49. }
  50. creation = DatabaseWrapper(settings_dict).creation
  51. self.assertEqual(creation._get_test_db_name(), creation.connection.settings_dict['TEST']['NAME'])
  52. @unittest.skipUnless(connection.vendor == 'sqlite', 'Test only for SQLite')
  53. @override_settings(DEBUG=True)
  54. class LastExecutedQueryTest(TestCase):
  55. def test_no_interpolation(self):
  56. # This shouldn't raise an exception (#17158)
  57. query = "SELECT strftime('%Y', 'now');"
  58. connection.cursor().execute(query)
  59. self.assertEqual(connection.queries[-1]['sql'], query)
  60. def test_parameter_quoting(self):
  61. # The implementation of last_executed_queries isn't optimal. It's
  62. # worth testing that parameters are quoted (#14091).
  63. query = "SELECT %s"
  64. params = ["\"'\\"]
  65. connection.cursor().execute(query, params)
  66. # Note that the single quote is repeated
  67. substituted = "SELECT '\"''\\'"
  68. self.assertEqual(connection.queries[-1]['sql'], substituted)
  69. def test_large_number_of_parameters(self):
  70. # If SQLITE_MAX_VARIABLE_NUMBER (default = 999) has been changed to be
  71. # greater than SQLITE_MAX_COLUMN (default = 2000), last_executed_query
  72. # can hit the SQLITE_MAX_COLUMN limit (#26063).
  73. with connection.cursor() as cursor:
  74. sql = "SELECT MAX(%s)" % ", ".join(["%s"] * 2001)
  75. params = list(range(2001))
  76. # This should not raise an exception.
  77. cursor.db.ops.last_executed_query(cursor.cursor, sql, params)
  78. @unittest.skipUnless(connection.vendor == 'sqlite', 'SQLite tests')
  79. class EscapingChecks(TestCase):
  80. """
  81. All tests in this test case are also run with settings.DEBUG=True in
  82. EscapingChecksDebug test case, to also test CursorDebugWrapper.
  83. """
  84. def test_parameter_escaping(self):
  85. # '%s' escaping support for sqlite3 (#13648).
  86. with connection.cursor() as cursor:
  87. cursor.execute("select strftime('%s', date('now'))")
  88. response = cursor.fetchall()[0][0]
  89. # response should be an non-zero integer
  90. self.assertTrue(int(response))
  91. @unittest.skipUnless(connection.vendor == 'sqlite', 'SQLite tests')
  92. @override_settings(DEBUG=True)
  93. class EscapingChecksDebug(EscapingChecks):
  94. pass
  95. @unittest.skipUnless(connection.vendor == 'sqlite', 'SQLite tests')
  96. class ThreadSharing(TransactionTestCase):
  97. available_apps = ['backends']
  98. def test_database_sharing_in_threads(self):
  99. def create_object():
  100. Object.objects.create()
  101. create_object()
  102. thread = threading.Thread(target=create_object)
  103. thread.start()
  104. thread.join()
  105. self.assertEqual(Object.objects.count(), 2)