diff --git a/src/testcontainers/core/wait_strategies.py b/src/testcontainers/core/wait_strategies.py index 4e9f5a77..eaa04b9b 100644 --- a/src/testcontainers/core/wait_strategies.py +++ b/src/testcontainers/core/wait_strategies.py @@ -139,12 +139,16 @@ def wait_until_ready(self, container: "WaitStrategyTarget") -> None: wrapped.reload() if wrapped.status not in _NOT_EXITED_STATUSES: # Get exit information for better debugging + stdout_str, stderr_str = _get_container_logs_for_debugging(container) status_info = _get_container_status_info(container) + message_pattern = self._message.pattern if hasattr(self._message, "pattern") else str(self._message) raise RuntimeError( f"Container exited (status: {status_info['status']}, exit code: {status_info['exit_code']}) " - f"before emitting logs containing '{self._message.pattern if hasattr(self._message, 'pattern') else str(self._message)}'. " + f"before emitting logs containing '{message_pattern}'. " f"Container error: {status_info['error']}. " + f"Recent stdout: {stdout_str}. " + f"Recent stderr: {stderr_str}. " f"Hint: Check container logs and ensure the application is configured to start correctly. " f"The application may be crashing or exiting early." ) diff --git a/tests/core/test_wait_strategies.py b/tests/core/test_wait_strategies.py index 60c1be57..ab184bdd 100644 --- a/tests/core/test_wait_strategies.py +++ b/tests/core/test_wait_strategies.py @@ -157,6 +157,30 @@ def test_wait_until_ready(self, mock_sleep, mock_time, container_logs, expected_ with pytest.raises(TimeoutError): strategy.wait_until_ready(mock_container) + @patch("time.sleep") + def test_wait_until_ready_includes_logs_when_container_exits(self, mock_sleep): + strategy = LogMessageWaitStrategy("waiting for connections") + mock_container = Mock() + mock_container.get_logs.return_value = ( + b"Fatal: unknown option", + b"stderr diagnostic line", + ) + mock_wrapped = Mock() + mock_wrapped.status = "exited" + mock_wrapped.reload.return_value = None + mock_container.get_wrapped_container.return_value = mock_wrapped + + with patch( + "testcontainers.core.waiting_utils._get_container_status_info", + return_value={"status": "exited", "exit_code": "1", "error": "", "health_status": "none"}, + ): + with pytest.raises(RuntimeError, match="Recent stdout: .*Fatal: unknown option") as exc_info: + strategy.wait_until_ready(mock_container) + + error_message = str(exc_info.value) + assert "Recent stderr: stderr diagnostic line" in error_message + assert "exit code: 1" in error_message + class TestHttpWaitStrategy: """Test the HttpWaitStrategy class."""