Opened 6 months ago

Last modified 6 months ago

#35548 assigned Bug

An error in TestCase.setUpTestData() leaks data on databases without transactions

Reported by: Tim Graham Owned by: Rish
Component: Testing framework Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

While working on a backend for MongoDB, I found that an exception on the fourth line of expressions.tests.ExpressionsNumericTests.setUpTestData left Number rows in the database such that a later test failed like this:

======================================================================
ERROR: test_F_reuse (expressions.tests.ExpressionsTests.test_F_reuse)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/tests/expressions/tests.py", line 1217, in test_F_reuse
    self.assertEqual(n_qs.get(), n)
                     ^^^^^^^^^^
  File "/home/tim/code/django/django/db/models/query.py", line 652, in get
    raise self.model.MultipleObjectsReturned(
expressions.models.Number.MultipleObjectsReturned: get() returned more than one Number -- it returned more than 20!

This is the same problem as #25176 but for databases with DatabaseFeatures.supports_transactions = False.

Change History (4)

comment:1 by Simon Charette, 6 months ago

Triage Stage: UnreviewedAccepted

I think the following should do and also avoid a lack of rolling back transaction when they are supported

  • django/test/testcases.py

    diff --git a/django/test/testcases.py b/django/test/testcases.py
    index f1c6b5ae9c..5cd90a7415 100644
    a b  
    77import threading
    88import unittest
    99from collections import Counter
    10 from contextlib import contextmanager
     10from contextlib import contextmanager, suppress
    1111from copy import copy, deepcopy
    1212from difflib import get_close_matches
    1313from functools import wraps
    def _pre_setup(self):  
    11251125        try:
    11261126            self._fixture_setup()
    11271127        except Exception:
     1128            # Attempt to teardown fixtures on exception during setup as
     1129            # `_post_teardown` won't be triggered to cleanup state when an
     1130            # an exception is surfaced to `SimpleTestCase._pre_setup`.
     1131            with suppress(Exception):
     1132                self._fixture_teardown()
    11281133            if self.available_apps is not None:
    11291134                apps.unset_available_apps()
    11301135                setting_changed.send(

Only lightly tested though.

comment:2 by Rish, 6 months ago

Owner: changed from nobody to Rish
Status: newassigned

comment:3 by Rish, 6 months ago

Has patch: set

comment:4 by Tim Graham, 6 months ago

Needs tests: set

The PR lacks any tests. Perhaps inspiration could be taken from 0abb06930fc0686cb35079934e5bb40df66f5691.

Note: See TracTickets for help on using tickets.
Back to Top