From b9fd09d21b722c3745501151f9cbd5b95ccc3177 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Thu, 26 Nov 2020 10:07:18 +0000 Subject: [PATCH] Fixed #32227 -- Prevented crash when setUpTestData() errors with --debug-sql. Thanks Mariusz Felisiak for the report. --- django/test/runner.py | 10 ++++++++-- tests/test_runner/test_debug_sql.py | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/django/test/runner.py b/django/test/runner.py index 83f06c72f3..8e6c29b0b4 100644 --- a/django/test/runner.py +++ b/django/test/runner.py @@ -38,6 +38,7 @@ class DebugSQLTextTestResult(unittest.TextTestResult): def __init__(self, stream, descriptions, verbosity): self.logger = logging.getLogger('django.db.backends') self.logger.setLevel(logging.DEBUG) + self.debug_sql_stream = None super().__init__(stream, descriptions, verbosity) def startTest(self, test): @@ -56,8 +57,13 @@ class DebugSQLTextTestResult(unittest.TextTestResult): def addError(self, test, err): super().addError(test, err) - self.debug_sql_stream.seek(0) - self.errors[-1] = self.errors[-1] + (self.debug_sql_stream.read(),) + if self.debug_sql_stream is None: + # Error before tests e.g. in setUpTestData(). + sql = '' + else: + self.debug_sql_stream.seek(0) + sql = self.debug_sql_stream.read() + self.errors[-1] = self.errors[-1] + (sql,) def addFailure(self, test, err): super().addFailure(test, err) diff --git a/tests/test_runner/test_debug_sql.py b/tests/test_runner/test_debug_sql.py index 8c4cb6fef6..0e8e4207d6 100644 --- a/tests/test_runner/test_debug_sql.py +++ b/tests/test_runner/test_debug_sql.py @@ -25,6 +25,14 @@ class TestDebugSQL(unittest.TestCase): Person.objects.filter(first_name='error').count() raise Exception + class ErrorSetUpTestDataTest(TestCase): + @classmethod + def setUpTestData(cls): + raise Exception + + def runTest(self): + pass + class PassingSubTest(TestCase): def runTest(self): with self.subTest(): @@ -107,3 +115,22 @@ class TestDebugSQL(unittest.TestCase): '''FROM "test_runner_person" WHERE ''' '''"test_runner_person"."first_name" = 'subtest-pass';'''), ] + + def test_setupclass_exception(self): + runner = DiscoverRunner(debug_sql=True, verbosity=0) + suite = runner.test_suite() + suite.addTest(self.ErrorSetUpTestDataTest()) + old_config = runner.setup_databases() + stream = StringIO() + runner.test_runner( + verbosity=0, + stream=stream, + resultclass=runner.get_resultclass(), + ).run(suite) + runner.teardown_databases(old_config) + output = stream.getvalue() + self.assertIn( + 'ERROR: setUpClass ' + '(test_runner.test_debug_sql.TestDebugSQL.ErrorSetUpTestDataTest)', + output, + )