﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
36429	IntegrityError on contentype creation when using transactional test with AND without serialized_rollback	Julie Rymer	Clifford Gama	"Related to #23727

When using `TransactionTestCase`, if you use rollback emulation with `serialized_rollback=True` for some test but **not all**, you'll get a db error because of a duplicate on ContentType.

{{{
django.db.utils.IntegrityError: UNIQUE constraint failed: django_content_type.app_label, django_content_type.model

Traceback (most recent call last):
  File ""[...]/site-packages/django/db/backends/base/creation.py"", line 163, in deserialize_db_from_string
    obj.save()

}}}


== Problem analysis

When using `serialized_rollback=True`, on test setup the content of the database that was previously serialised will be applied.
On teardown, the data will be flushed and the post_migrate signal won't be emitted because of `inhibit_post_migrate` argument.

When using `serialized_rollback=False` no database content is loaded on setup and on teardown the database is flushed and post_migrate signal will be emitted.

ContentType objects get created from a post_migrate handler. They also get serialised from database content.

So, what happens if a test with `serialized_rollback=True` get run **after** a test with `serialized_rollback=False`? You get an IntegrityError because the ContentType object are loaded from `connection._test_serialized_contents` after they already were created from the post_migrate handler emitted when flushing.

I think this is what is happening, please correct me if my assumptions are wrong.


== How to reproduce

Using the ""Writing your first Django app"" tutorial, you can reproduce by adding the following tests to the polls app:

{{{

from django.test import TransactionTestCase

class QuestionModel1Tests(TransactionTestCase):
    serialized_rollback = False
    def test_was_published_recently_with_future_question(self):
        self.assertTrue(True)


class QuestionModel2Tests(TransactionTestCase):
    serialized_rollback = True
    def test_was_published_recently_with_future_question(self):
        self.assertTrue(True)
}}}

This error fully depends on the order of the test execution. If you don't get the error the first time, just add some more tests alternating `serialized_rollback` True and False until you get the error. you'll get it as soon as a serialised rollback test execute after a non-serialised one."	Bug	assigned	Testing framework	5.2	Normal				Accepted	0	0	0	0	0	0
