From 612247b3a0acbdec17b9c52410b2349533ff2d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anssi=20K=C3=A4=C3=A4ri=C3=A4inen?= Date: Tue, 24 Apr 2012 16:47:31 +0000 Subject: [PATCH] Fixed #16961 -- Skipped resetting AUTO_INCREMENT fields for MySQL if the server version is greater than 5.0.12. This allows for much faster testing. Thanks to aigarius for the report and claudep and ramiro for review. git-svn-id: http://code.djangoproject.com/svn/django/trunk@17932 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/backends/mysql/base.py | 20 +++++++++------- tests/regressiontests/backends/tests.py | 26 ++++++++++++++++++++- tests/regressiontests/test_runner/models.py | 5 ++++ tests/regressiontests/test_runner/tests.py | 25 +++++++++++++++++++- 4 files changed, 65 insertions(+), 11 deletions(-) diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index c1ef625bb6..bacd998fa5 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -261,15 +261,17 @@ class DatabaseOperations(BaseDatabaseOperations): sql.append('%s %s;' % (style.SQL_KEYWORD('TRUNCATE'), style.SQL_FIELD(self.quote_name(table)))) sql.append('SET FOREIGN_KEY_CHECKS = 1;') - # 'ALTER TABLE table AUTO_INCREMENT = 1;'... style SQL statements - # to reset sequence indices - sql.extend(["%s %s %s %s %s;" % \ - (style.SQL_KEYWORD('ALTER'), - style.SQL_KEYWORD('TABLE'), - style.SQL_TABLE(self.quote_name(sequence['table'])), - style.SQL_KEYWORD('AUTO_INCREMENT'), - style.SQL_FIELD('= 1'), - ) for sequence in sequences]) + # Truncate already resets the AUTO_INCREMENT field from + # MySQL version 5.0.13 onwards. Refs #16961. + if self.connection.mysql_version < (5,0,13): + sql.extend( + ["%s %s %s %s %s;" % \ + (style.SQL_KEYWORD('ALTER'), + style.SQL_KEYWORD('TABLE'), + style.SQL_TABLE(self.quote_name(sequence['table'])), + style.SQL_KEYWORD('AUTO_INCREMENT'), + style.SQL_FIELD('= 1'), + ) for sequence in sequences]) return sql else: return [] diff --git a/tests/regressiontests/backends/tests.py b/tests/regressiontests/backends/tests.py index d5b1ea82bf..9b28787c15 100644 --- a/tests/regressiontests/backends/tests.py +++ b/tests/regressiontests/backends/tests.py @@ -61,10 +61,34 @@ class OracleChecks(unittest.TestCase): def test_client_encoding(self): # If the backend is Oracle, test that the client encoding is set # correctly. This was broken under Cygwin prior to r14781. - c = connection.cursor() # Ensure the connection is initialized. + connection.cursor() # Ensure the connection is initialized. self.assertEqual(connection.connection.encoding, "UTF-8") self.assertEqual(connection.connection.nencoding, "UTF-8") +class MySQLTests(TestCase): + @unittest.skipUnless(connection.vendor == 'mysql', + "Test valid only for MySQL") + def test_autoincrement(self): + """ + Check that auto_increment fields are reset correctly by sql_flush(). + Before MySQL version 5.0.13 TRUNCATE did not do auto_increment reset. + Refs #16961. + """ + statements = connection.ops.sql_flush(no_style(), + tables=['test'], + sequences=[{ + 'table': 'test', + 'col': 'somecol', + }]) + found_reset = False + for sql in statements: + found_reset = found_reset or 'ALTER TABLE' in sql + if connection.mysql_version < (5,0,13): + self.assertTrue(found_reset) + else: + self.assertFalse(found_reset) + + class DateQuotingTest(TestCase): def test_django_date_trunc(self): diff --git a/tests/regressiontests/test_runner/models.py b/tests/regressiontests/test_runner/models.py index e69de29bb2..9a072e627c 100644 --- a/tests/regressiontests/test_runner/models.py +++ b/tests/regressiontests/test_runner/models.py @@ -0,0 +1,5 @@ +from django.db import models + +class Person(models.Model): + first_name = models.CharField(max_length=20) + last_name = models.CharField(max_length=20) diff --git a/tests/regressiontests/test_runner/tests.py b/tests/regressiontests/test_runner/tests.py index 2af4eb9750..9f8085b5b6 100644 --- a/tests/regressiontests/test_runner/tests.py +++ b/tests/regressiontests/test_runner/tests.py @@ -8,13 +8,15 @@ from optparse import make_option from django.core.exceptions import ImproperlyConfigured from django.core.management import call_command from django import db -from django.test import simple +from django.db import connection +from django.test import simple, TransactionTestCase from django.test.simple import DjangoTestSuiteRunner, get_tests from django.test.testcases import connections_support_transactions from django.utils import unittest from django.utils.importlib import import_module from ..admin_scripts.tests import AdminScriptTestCase +from .models import Person TEST_APP_OK = 'regressiontests.test_runner.valid_app.models' @@ -281,3 +283,24 @@ class Sqlite3InMemoryTestDbs(unittest.TestCase): self.assertTrue(connections_support_transactions(), msg) finally: db.connections = old_db_connections + + +class AutoIncrementResetTest(TransactionTestCase): + """ + Here we test creating the same model two times in different test methods, + and check that both times they get "1" as their PK value. That is, we test + that AutoField values start from 1 for each transactional test case. + """ + @unittest.skipIf(connection.vendor == 'oracle', + "Oracle's auto-increment fields are not reset between " + "tests") + def test_autoincrement_reset1(self): + p = Person.objects.create(first_name='Jack', last_name='Smith') + self.assertEquals(p.pk, 1) + + @unittest.skipIf(connection.vendor == 'oracle', + "Oracle's auto-increment fields are not reset between " + "tests") + def test_autoincrement_reset2(self): + p = Person.objects.create(first_name='Jack', last_name='Smith') + self.assertEquals(p.pk, 1)