mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #27079 -- Avoided multiple setUpClass()/tearDownClass() calls in LiveServerTestCase tests.
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							cbd9f8531d
						
					
				
				
					commit
					def09bf412
				
			| @@ -1533,7 +1533,11 @@ class LiveServerTestCase(TransactionTestCase): | ||||
|             ALLOWED_HOSTS={'append': cls.allowed_host}, | ||||
|         ) | ||||
|         cls._live_server_modified_settings.enable() | ||||
|         cls.addClassCleanup(cls._live_server_modified_settings.disable) | ||||
|         cls._start_server_thread() | ||||
|  | ||||
|     @classmethod | ||||
|     def _start_server_thread(cls): | ||||
|         connections_override = cls._make_connections_override() | ||||
|         for conn in connections_override.values(): | ||||
|             # Explicitly enable thread-shareability for this connection. | ||||
| @@ -1542,13 +1546,11 @@ class LiveServerTestCase(TransactionTestCase): | ||||
|         cls.server_thread = cls._create_server_thread(connections_override) | ||||
|         cls.server_thread.daemon = True | ||||
|         cls.server_thread.start() | ||||
|         cls.addClassCleanup(cls._terminate_thread) | ||||
|  | ||||
|         # Wait for the live server to be ready | ||||
|         cls.server_thread.is_ready.wait() | ||||
|         if cls.server_thread.error: | ||||
|             # Clean up behind ourselves, since tearDownClass won't get called in | ||||
|             # case of errors. | ||||
|             cls._tearDownClassInternal() | ||||
|             raise cls.server_thread.error | ||||
|  | ||||
|     @classmethod | ||||
| @@ -1561,20 +1563,13 @@ class LiveServerTestCase(TransactionTestCase): | ||||
|         ) | ||||
|  | ||||
|     @classmethod | ||||
|     def _tearDownClassInternal(cls): | ||||
|     def _terminate_thread(cls): | ||||
|         # Terminate the live server's thread. | ||||
|         cls.server_thread.terminate() | ||||
|         # Restore shared connections' non-shareability. | ||||
|         for conn in cls.server_thread.connections_override.values(): | ||||
|             conn.dec_thread_sharing() | ||||
|  | ||||
|         cls._live_server_modified_settings.disable() | ||||
|         super().tearDownClass() | ||||
|  | ||||
|     @classmethod | ||||
|     def tearDownClass(cls): | ||||
|         cls._tearDownClassInternal() | ||||
|  | ||||
|  | ||||
| class SerializeMixin: | ||||
|     """ | ||||
|   | ||||
| @@ -127,18 +127,12 @@ class LiveServerTestCaseSetupTest(LiveServerBase): | ||||
|             super().setUpClass() | ||||
|         except RuntimeError: | ||||
|             # LiveServerTestCase's change to ALLOWED_HOSTS should be reverted. | ||||
|             cls.doClassCleanups() | ||||
|             cls.check_allowed_hosts(['testserver']) | ||||
|         else: | ||||
|             raise RuntimeError('Server did not fail.') | ||||
|         cls.set_up_called = True | ||||
|  | ||||
|     @classmethod | ||||
|     def tearDownClass(cls): | ||||
|         # Make tearDownClass() a no-op because setUpClass() was already cleaned | ||||
|         # up, and because the error inside setUpClass() was handled, which will | ||||
|         # cause tearDownClass() to be called when it normally wouldn't. | ||||
|         pass | ||||
|  | ||||
|     def test_set_up_class(self): | ||||
|         self.assertIs(self.set_up_called, True) | ||||
|  | ||||
| @@ -334,7 +328,7 @@ class LiveServerPort(LiveServerBase): | ||||
|         """ | ||||
|         TestCase = type("TestCase", (LiveServerBase,), {}) | ||||
|         try: | ||||
|             TestCase.setUpClass() | ||||
|             TestCase._start_server_thread() | ||||
|         except OSError as e: | ||||
|             if e.errno == errno.EADDRINUSE: | ||||
|                 # We're out of ports, LiveServerTestCase correctly fails with | ||||
| @@ -342,15 +336,12 @@ class LiveServerPort(LiveServerBase): | ||||
|                 return | ||||
|             # Unexpected error. | ||||
|             raise | ||||
|         try: | ||||
|             # We've acquired a port, ensure our server threads acquired | ||||
|             # different addresses. | ||||
|             self.assertNotEqual( | ||||
|                 self.live_server_url, TestCase.live_server_url, | ||||
|                 "Acquired duplicate server addresses for server threads: %s" % self.live_server_url | ||||
|             ) | ||||
|         finally: | ||||
|             TestCase.tearDownClass() | ||||
|         self.assertNotEqual( | ||||
|             self.live_server_url, | ||||
|             TestCase.live_server_url, | ||||
|             f'Acquired duplicate server addresses for server threads: ' | ||||
|             f'{self.live_server_url}', | ||||
|         ) | ||||
|  | ||||
|     def test_specified_port_bind(self): | ||||
|         """LiveServerTestCase.port customizes the server's port.""" | ||||
| @@ -360,14 +351,13 @@ class LiveServerPort(LiveServerBase): | ||||
|         s.bind(('', 0)) | ||||
|         TestCase.port = s.getsockname()[1] | ||||
|         s.close() | ||||
|         TestCase.setUpClass() | ||||
|         try: | ||||
|             self.assertEqual( | ||||
|                 TestCase.port, TestCase.server_thread.port, | ||||
|                 'Did not use specified port for LiveServerTestCase thread: %s' % TestCase.port | ||||
|             ) | ||||
|         finally: | ||||
|             TestCase.tearDownClass() | ||||
|         TestCase._start_server_thread() | ||||
|         self.assertEqual( | ||||
|             TestCase.port, | ||||
|             TestCase.server_thread.port, | ||||
|             f'Did not use specified port for LiveServerTestCase thread: ' | ||||
|             f'{TestCase.port}', | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class LiveServerThreadedTests(LiveServerBase): | ||||
|   | ||||
| @@ -29,22 +29,8 @@ class LiveServerBase(StaticLiveServerTestCase): | ||||
|         # Override settings | ||||
|         cls.settings_override = override_settings(**TEST_SETTINGS) | ||||
|         cls.settings_override.enable() | ||||
|         try: | ||||
|             super().setUpClass() | ||||
|         except Exception: | ||||
|             # Clean up since tearDownClass() isn't called on errors. | ||||
|             cls._tearDownLiveServerBase() | ||||
|             raise | ||||
|  | ||||
|     @classmethod | ||||
|     def _tearDownLiveServerBase(cls): | ||||
|         # Restore original settings | ||||
|         cls.settings_override.disable() | ||||
|  | ||||
|     @classmethod | ||||
|     def tearDownClass(cls): | ||||
|         super().tearDownClass() | ||||
|         cls._tearDownLiveServerBase() | ||||
|         cls.addClassCleanup(cls.settings_override.disable) | ||||
|         super().setUpClass() | ||||
|  | ||||
|  | ||||
| class StaticLiveServerChecks(LiveServerBase): | ||||
| @@ -74,8 +60,6 @@ class StaticLiveServerChecks(LiveServerBase): | ||||
|             # app without having set the required STATIC_URL setting.") | ||||
|             pass | ||||
|         else: | ||||
|             # super().setUpClass() cleans up after itself on a failure. | ||||
|             super().tearDownClass() | ||||
|             raise Exception('setUpClass() should have raised an exception.') | ||||
|  | ||||
|     def test_test_test(self): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user