43bc58770d
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
158 lines
6.1 KiB
Python
158 lines
6.1 KiB
Python
"""
|
|
Tests for app/tasks/monitor_stalled_steps.py
|
|
|
|
This module tests the periodic task that monitors and recovers stalled processing steps.
|
|
"""
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestMonitorStalledSteps:
|
|
"""Test monitor_stalled_steps task."""
|
|
|
|
@patch("app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed")
|
|
@patch("app.tasks.monitor_stalled_steps.SessionLocal")
|
|
def test_monitor_stalled_steps_no_stalled(self, mock_session_local, mock_mark_stalled):
|
|
"""Test monitor_stalled_steps when no stalled steps found."""
|
|
from app.tasks.monitor_stalled_steps import monitor_stalled_steps
|
|
|
|
# Mock database session
|
|
mock_db = MagicMock()
|
|
mock_session_local.return_value.__enter__.return_value = mock_db
|
|
|
|
# No stalled steps
|
|
mock_mark_stalled.return_value = 0
|
|
|
|
# Run task
|
|
result = monitor_stalled_steps()
|
|
|
|
# Verify result
|
|
assert result == {"recovered": 0}
|
|
mock_mark_stalled.assert_called_once_with(mock_db)
|
|
|
|
@patch("app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed")
|
|
@patch("app.tasks.monitor_stalled_steps.SessionLocal")
|
|
def test_monitor_stalled_steps_with_stalled(self, mock_session_local, mock_mark_stalled):
|
|
"""Test monitor_stalled_steps when stalled steps are found."""
|
|
from app.tasks.monitor_stalled_steps import monitor_stalled_steps
|
|
|
|
# Mock database session
|
|
mock_db = MagicMock()
|
|
mock_session_local.return_value.__enter__.return_value = mock_db
|
|
|
|
# Found 3 stalled steps
|
|
mock_mark_stalled.return_value = 3
|
|
|
|
# Run task
|
|
result = monitor_stalled_steps()
|
|
|
|
# Verify result
|
|
assert result == {"recovered": 3}
|
|
mock_mark_stalled.assert_called_once_with(mock_db)
|
|
|
|
@patch("app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed")
|
|
@patch("app.tasks.monitor_stalled_steps.SessionLocal")
|
|
@patch("app.tasks.monitor_stalled_steps.logger")
|
|
def test_monitor_stalled_steps_logs_recovery(self, mock_logger, mock_session_local, mock_mark_stalled):
|
|
"""Test that monitor_stalled_steps logs recovery actions."""
|
|
from app.tasks.monitor_stalled_steps import monitor_stalled_steps
|
|
|
|
# Mock database session
|
|
mock_db = MagicMock()
|
|
mock_session_local.return_value.__enter__.return_value = mock_db
|
|
|
|
# Found 2 stalled steps
|
|
mock_mark_stalled.return_value = 2
|
|
|
|
# Run task
|
|
result = monitor_stalled_steps()
|
|
|
|
# Verify logging
|
|
mock_logger.warning.assert_called_once()
|
|
log_message = mock_logger.warning.call_args[0][0]
|
|
assert "Recovered 2 stalled step(s)" in log_message
|
|
|
|
@patch("app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed")
|
|
@patch("app.tasks.monitor_stalled_steps.SessionLocal")
|
|
@patch("app.tasks.monitor_stalled_steps.logger")
|
|
def test_monitor_stalled_steps_logs_debug_when_none(self, mock_logger, mock_session_local, mock_mark_stalled):
|
|
"""Test that monitor_stalled_steps logs debug message when no stalled steps."""
|
|
from app.tasks.monitor_stalled_steps import monitor_stalled_steps
|
|
|
|
# Mock database session
|
|
mock_db = MagicMock()
|
|
mock_session_local.return_value.__enter__.return_value = mock_db
|
|
|
|
# No stalled steps
|
|
mock_mark_stalled.return_value = 0
|
|
|
|
# Run task
|
|
result = monitor_stalled_steps()
|
|
|
|
# Verify debug logging
|
|
mock_logger.debug.assert_called_once()
|
|
log_message = mock_logger.debug.call_args[0][0]
|
|
assert "No stalled steps found" in log_message
|
|
|
|
@patch("app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed")
|
|
@patch("app.tasks.monitor_stalled_steps.SessionLocal")
|
|
@patch("app.tasks.monitor_stalled_steps.logger")
|
|
def test_monitor_stalled_steps_handles_exceptions(self, mock_logger, mock_session_local, mock_mark_stalled):
|
|
"""Test that monitor_stalled_steps handles exceptions gracefully."""
|
|
from app.tasks.monitor_stalled_steps import monitor_stalled_steps
|
|
|
|
# Mock database session
|
|
mock_db = MagicMock()
|
|
mock_session_local.return_value.__enter__.return_value = mock_db
|
|
|
|
# Simulate an exception
|
|
mock_mark_stalled.side_effect = Exception("Database error")
|
|
|
|
# Run task
|
|
result = monitor_stalled_steps()
|
|
|
|
# Verify error handling
|
|
assert result == {"error": "Database error", "recovered": 0}
|
|
mock_logger.error.assert_called_once()
|
|
|
|
@patch("app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed")
|
|
@patch("app.tasks.monitor_stalled_steps.SessionLocal")
|
|
def test_monitor_stalled_steps_uses_context_manager(self, mock_session_local, mock_mark_stalled):
|
|
"""Test that monitor_stalled_steps uses context manager for database session."""
|
|
from app.tasks.monitor_stalled_steps import monitor_stalled_steps
|
|
|
|
# Mock database session
|
|
mock_db = MagicMock()
|
|
mock_context = MagicMock()
|
|
mock_context.__enter__ = MagicMock(return_value=mock_db)
|
|
mock_context.__exit__ = MagicMock(return_value=False)
|
|
mock_session_local.return_value = mock_context
|
|
|
|
mock_mark_stalled.return_value = 0
|
|
|
|
# Run task
|
|
result = monitor_stalled_steps()
|
|
|
|
# Verify context manager was used
|
|
mock_context.__enter__.assert_called_once()
|
|
mock_context.__exit__.assert_called_once()
|
|
|
|
def test_monitor_stalled_steps_is_celery_task(self):
|
|
"""Test that monitor_stalled_steps is registered as a Celery task."""
|
|
from app.tasks.monitor_stalled_steps import monitor_stalled_steps
|
|
|
|
# Should have task attributes
|
|
assert hasattr(monitor_stalled_steps, "apply_async")
|
|
assert hasattr(monitor_stalled_steps, "delay")
|
|
assert callable(monitor_stalled_steps)
|
|
|
|
def test_monitor_stalled_steps_task_name(self):
|
|
"""Test that monitor_stalled_steps has correct task name."""
|
|
from app.tasks.monitor_stalled_steps import monitor_stalled_steps
|
|
|
|
# Check task name
|
|
assert monitor_stalled_steps.name == "app.tasks.monitor_stalled_steps.monitor_stalled_steps"
|