diff options
author | Aymeric Augustin <aymeric.augustin@m4x.org> | 2014-07-28 14:30:41 +0200 |
---|---|---|
committer | Aymeric Augustin <aymeric.augustin@m4x.org> | 2014-07-28 14:30:41 +0200 |
commit | 729e4ae4f0730585ac4640e7fa3aa06374677ff2 (patch) | |
tree | ed724443e2dfc55150a518959ef44c299b6a9e71 /tests/transactions | |
parent | 53a61d82b38b7c39fa8ec4bd3047014694e96f60 (diff) | |
download | django-729e4ae4f0730585ac4640e7fa3aa06374677ff2.tar.gz |
Fixed #23074 -- Avoided leaking savepoints in atomic.
Thanks Chow Loong Jin for the report and the initial patch.
Diffstat (limited to 'tests/transactions')
-rw-r--r-- | tests/transactions/tests.py | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/tests/transactions/tests.py b/tests/transactions/tests.py index 72e600d41d..005df0ba91 100644 --- a/tests/transactions/tests.py +++ b/tests/transactions/tests.py @@ -403,3 +403,25 @@ class AtomicMiscTests(TransactionTestCase): pass # Must not raise an exception transaction.atomic(Callable()) + + @skipUnlessDBFeature('can_release_savepoints') + def test_atomic_does_not_leak_savepoints_on_failure(self): + # Regression test for #23074 + + # Expect an error when rolling back a savepoint that doesn't exist. + # Done outside of the transaction block to ensure proper recovery. + with self.assertRaises(Error): + + # Start a plain transaction. + with transaction.atomic(): + + # Swallow the intentional error raised in the sub-transaction. + with six.assertRaisesRegex(self, Exception, "Oops"): + + # Start a sub-transaction with a savepoint. + with transaction.atomic(): + sid = connection.savepoint_ids[-1] + raise Exception("Oops") + + # This is expected to fail because the savepoint no longer exists. + connection.savepoint_rollback(sid) |