Make TestModelsLoaderMixin more transaction-friendly and evolution-friendly.

Review Request #11268 — Created Nov. 5, 2020 and submitted

Information

Djblets
release-2.0.x

Reviewers

TestModelsLoaderMixin attempted to set up some initial state for a
test suite, and then manage the database state per-test. The way it did
this made some bad assumptions that held up in earlier versions of
Django and with older versions of Django Evolution, but weren't quite
correct, and fails with Django Evolution 2.1.

The old code tried to perform a migrate at the start of each test, and
a flush at the end. These were often being done within a transaction
(set up by TestCase.setUpClass()), which currently fails with Django
Evolution (since it cancels the upgrade if in a transaction) and would
fail with Django's own migrate if run on MySQL (for the same reason).

The new code has been reworked to perform all the necessary operations
within setUpClass()/tearDownClass(), outside of any transaction
management. This allows us to populate the database up-front, enter a
transaction, and roll it back per-test, rather than flushing the whole
database per-test.

A huge benefit is that there's a major performance gain for many of our
unit tests, dropping it from 90 seconds to 18 seconds on my local
machine.

All unit tests pass.

Summary ID
Make TestModelsLoaderMixin more transaction-friendly and evolution-friendly.
`TestModelsLoaderMixin` attempted to set up some initial state for a test suite, and then manage the database state per-test. The way it did this made some bad assumptions that held up in earlier versions of Django and with older versions of Django Evolution, but weren't quite correct, and fails with Django Evolution 2.1. The old code tried to perform a `migrate` at the start of each test, and a `flush` at the end. These were often being done within a transaction (set up by `TestCase.setUpClass()`), which currently fails with Django Evolution (since it cancels the upgrade if in a transaction) and would fail with Django's own `migrate` if run on MySQL (for the same reason). The new code has been reworked to perform all the necessary operations within `setUpClass()`/`tearDownClass()`, outside of any transaction management. This allows us to populate the database up-front, enter a transaction, and roll it back per-test, rather than flushing the whole database per-test. A huge benefit is that there's a major performance gain for many of our unit tests, dropping it from 90 seconds to 18 seconds on my local machine.
5a34731be1d4468740950bcb7dfabac3971c6c29
david
  1. Ship It!
  2. 
      
chipx86
Review request changed
Status:
Completed
Change Summary:
Pushed to master (1dfac19)