fix(simple_metrics): update adaptive state even without thresholds so removed thresholds recover (SIENTIAPDE-2191)
This commit is contained in:
@@ -42,12 +42,17 @@ async def test_run(workflow_mock: AsyncMock, simple_metrics: SimpleMetrics):
|
||||
target_data = {'data': 'test_target_data'}
|
||||
simple_metrics_data = {'metrics': 'test_simple_metrics_data'}
|
||||
|
||||
workflow_mock.execute_activity_method = AsyncMock(side_effect=[target_data, None])
|
||||
workflow_mock.logger = MagicMock()
|
||||
workflow_mock.execute_activity_method = AsyncMock(side_effect=[target_data, None, None])
|
||||
workflow_mock.execute_local_activity_method = AsyncMock(return_value=simple_metrics_data)
|
||||
|
||||
# Act
|
||||
await simple_metrics.run(input_data)
|
||||
|
||||
# Assert - load, export and adaptive state (no thresholds still updates it)
|
||||
assert workflow_mock.execute_activity_method.call_count == 3
|
||||
workflow_mock.logger.warning.assert_not_called()
|
||||
|
||||
# Assert - Check load_custom_query call
|
||||
# Query format matches psycopg2.sql output (identifiers with double quotes, literals with single quotes)
|
||||
expected_query = f"""
|
||||
@@ -130,13 +135,22 @@ async def test_run_empty_target_data(workflow_mock: AsyncMock, simple_metrics: S
|
||||
|
||||
target_data = None
|
||||
|
||||
workflow_mock.logger = MagicMock()
|
||||
workflow_mock.execute_activity_method = AsyncMock(return_value=target_data)
|
||||
workflow_mock.execute_local_activity_method = AsyncMock()
|
||||
|
||||
# Act
|
||||
await simple_metrics.run(input_data)
|
||||
|
||||
# Assert - Should not call calculate_simple_metrics or export
|
||||
assert workflow_mock.execute_activity_method.call_count == 1
|
||||
# Assert - No calculate or export; load + adaptive state (empty window = healthy run)
|
||||
workflow_mock.execute_local_activity_method.assert_not_called()
|
||||
calls = workflow_mock.execute_activity_method.call_args_list
|
||||
assert [c.args[0] for c in calls] == [
|
||||
Activities.load_custom_query,
|
||||
Activities.update_simple_metrics_adaptive_state,
|
||||
]
|
||||
assert calls[1].args[1]['simple_metrics'] == []
|
||||
workflow_mock.logger.warning.assert_not_called()
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
@@ -159,15 +173,22 @@ async def test_run_empty_simple_metrics(workflow_mock: AsyncMock, simple_metrics
|
||||
target_data = {'data': 'test_target_data'}
|
||||
simple_metrics_data = None
|
||||
|
||||
workflow_mock.logger = MagicMock()
|
||||
workflow_mock.execute_activity_method = AsyncMock(return_value=target_data)
|
||||
workflow_mock.execute_local_activity_method = AsyncMock(return_value=simple_metrics_data)
|
||||
|
||||
# Act
|
||||
await simple_metrics.run(input_data)
|
||||
|
||||
# Assert - Should call calculate_simple_metrics but not export
|
||||
workflow_mock.execute_activity_method.assert_called_once()
|
||||
# Assert - calculate returns None: no export, adaptive state gets [] (the `or []` is live)
|
||||
workflow_mock.execute_local_activity_method.assert_called_once()
|
||||
calls = workflow_mock.execute_activity_method.call_args_list
|
||||
assert [c.args[0] for c in calls] == [
|
||||
Activities.load_custom_query,
|
||||
Activities.update_simple_metrics_adaptive_state,
|
||||
]
|
||||
assert calls[1].args[1]['simple_metrics'] == []
|
||||
workflow_mock.logger.warning.assert_not_called()
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
@@ -190,12 +211,17 @@ async def test_run_default_metrics(workflow_mock: AsyncMock, simple_metrics: Sim
|
||||
target_data = {'data': 'test_target_data'}
|
||||
simple_metrics_data = {'metrics': 'test_simple_metrics_data'}
|
||||
|
||||
workflow_mock.execute_activity_method = AsyncMock(side_effect=[target_data, None])
|
||||
workflow_mock.logger = MagicMock()
|
||||
workflow_mock.execute_activity_method = AsyncMock(side_effect=[target_data, None, None])
|
||||
workflow_mock.execute_local_activity_method = AsyncMock(return_value=simple_metrics_data)
|
||||
|
||||
# Act
|
||||
await simple_metrics.run(input_data)
|
||||
|
||||
# Assert - all three activities ran (a swallowed exhausted side_effect would warn)
|
||||
assert workflow_mock.execute_activity_method.call_count == 3
|
||||
workflow_mock.logger.warning.assert_not_called()
|
||||
|
||||
# Assert - Check calculate_simple_metrics call with default metrics
|
||||
workflow_mock.execute_activity_method.assert_any_call(
|
||||
Activities.load_custom_query,
|
||||
@@ -305,13 +331,21 @@ async def test_run_updates_adaptive_state_after_export(workflow_mock, simple_met
|
||||
|
||||
@mark.asyncio
|
||||
@patch('laborious.workflows.simple_metrics.workflow', new_callable=AsyncMock)
|
||||
async def test_run_without_thresholds_skips_adaptive_state(workflow_mock, simple_metrics):
|
||||
workflow_mock.execute_activity_method = AsyncMock(side_effect=[[_ROW] * 3, None])
|
||||
async def test_run_without_thresholds_still_updates_adaptive_state(workflow_mock, simple_metrics):
|
||||
# No thresholds = never a breach; still calling lets an escalated doc recover after the
|
||||
# thresholds are removed.
|
||||
workflow_mock.logger = MagicMock()
|
||||
workflow_mock.execute_activity_method = AsyncMock(side_effect=[[_ROW] * 3, None, None])
|
||||
workflow_mock.execute_local_activity_method = AsyncMock(return_value=_BREACH_ROWS)
|
||||
|
||||
await simple_metrics.run(_input())
|
||||
|
||||
assert workflow_mock.execute_activity_method.call_count == 2
|
||||
calls = workflow_mock.execute_activity_method.call_args_list
|
||||
assert len(calls) == 3
|
||||
assert calls[2].args[0] is Activities.update_simple_metrics_adaptive_state
|
||||
assert calls[2].args[1]['thresholds'] is None
|
||||
assert calls[2].args[1]['simple_metrics'] == _BREACH_ROWS
|
||||
workflow_mock.logger.warning.assert_not_called()
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
|
||||
Reference in New Issue
Block a user