Repository navigation
fix: partial-failure warning must not claim Redis retention without Redis #59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| import asyncio | ||
| import json | ||
| import logging | ||
| from collections.abc import Generator | ||
| from datetime import datetime, timezone | ||
| from typing import Any, cast | ||
|
|
@@ -1011,3 +1012,49 @@ def test_protocol_compliance(self, agent_config: AgentConfig) -> None: | |
| """Test that GuardAgentHandler satisfies AgentHandlerProtocol.""" | ||
| handler = GuardAgentHandler(agent_config) | ||
| assert isinstance(handler, AgentHandlerProtocol) | ||
|
|
||
|
|
||
| class TestRetentionLogMessage: | ||
| """The partial-failure warning must describe where unsent items actually | ||
| wait: memory only, or memory plus Redis when a Redis handler is attached.""" | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_events_warning_without_redis_says_memory_only( | ||
| self, agent_config: AgentConfig, caplog: pytest.LogCaptureFixture | ||
| ) -> None: | ||
| handler = GuardAgentHandler(agent_config) | ||
| handler.buffer = AsyncMock() | ||
| handler.buffer.redis_handler = None | ||
| handler.buffer.requeue_events_in_memory = AsyncMock(return_value=[]) | ||
| handler.buffer.flush_events_with_keys = AsyncMock( | ||
| return_value=([MagicMock()], ["ek"]) | ||
| ) | ||
| handler.transport = AsyncMock() | ||
| handler.transport.send_events = AsyncMock(return_value=False) | ||
|
|
||
| with caplog.at_level(logging.WARNING, logger="guard_agent"): | ||
| await handler._flush_events() | ||
|
|
||
| assert "requeued in memory (events) for retry" in caplog.text | ||
| assert "retained in Redis" not in caplog.text | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_events_warning_with_redis_mentions_redis( | ||
| self, agent_config: AgentConfig, caplog: pytest.LogCaptureFixture | ||
| ) -> None: | ||
| handler = GuardAgentHandler(agent_config) | ||
| handler.buffer = AsyncMock() | ||
| handler.buffer.redis_handler = AsyncMock() | ||
| handler.buffer.requeue_events_in_memory = AsyncMock(return_value=[]) | ||
| handler.buffer.flush_events_with_keys = AsyncMock( | ||
| return_value=([MagicMock()], ["ek"]) | ||
| ) | ||
| handler.transport = AsyncMock() | ||
| handler.transport.send_events = AsyncMock(return_value=False) | ||
|
|
||
| with caplog.at_level(logging.WARNING, logger="guard_agent"): | ||
| await handler._flush_events() | ||
|
|
||
| assert ( | ||
| "requeued in memory and retained in Redis (events) for retry" in caplog.text | ||
| ) | ||
|
Comment on lines
+1015
to
+1060
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: sed -n '25,48p;100,150p' guard_agent/_client_flush.py
sed -n '1010,1065p' tests/test_client.py
rg -n '_flush_metrics|retained in Redis|requeued in memory' testsRepository: rennf93/guard-agent Length of output: 6353 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- changed files/stat ---'
git diff --stat ce8c8becf6c897328e36b39750c2ab40e572dece 8bbfc112727fea5ce1d4190d47ce73a027d3f24e
printf '%s\n' '--- client flush implementation ---'
cat -n guard_agent/_client_flush.py | sed -n '1,240p'
printf '%s\n' '--- metric-related tests in test_buffer.py ---'
cat -n tests/test_buffer.py | sed -n '360,500p;520,690p'
printf '%s\n' '--- metric-related tests in test_client.py and branch tests ---'
cat -n tests/test_client.py | sed -n '1,90p;950,1070p'
cat -n tests/test_client_branches.py | sed -n '150,230p'
printf '%s\n' '--- all warning assertions and metric flush callers ---'
rg -n -C 3 'caplog|warning|_flush_metrics|send_metrics|flush_metrics_with_keys|redis_handler' tests/test_client.py tests/test_client_branches.py tests/test_buffer.pyRepository: rennf93/guard-agent Length of output: 41954 Add a regression test for the metric warning. The new tests exercise only Add one no-Redis metric test that calls Suggested fix class TestRetentionLogMessage:
@@
async def test_events_warning_without_redis_says_memory_only(
self, agent_config: AgentConfig, caplog: pytest.LogCaptureFixture
) -> None:
@@
assert "requeued in memory (events) for retry" in caplog.text
assert "retained in Redis" not in caplog.text
+ `@pytest.mark.asyncio`
+ async def test_metrics_warning_without_redis_says_memory_only(
+ self, agent_config: AgentConfig, caplog: pytest.LogCaptureFixture
+ ) -> None:
+ handler = GuardAgentHandler(agent_config)
+ handler.buffer = AsyncMock()
+ handler.buffer.redis_handler = None
+ handler.buffer.requeue_metrics_in_memory = AsyncMock(return_value=[])
+ handler.buffer.flush_metrics_with_keys = AsyncMock(
+ return_value=([MagicMock()], ["mk"])
+ )
+ handler.transport = AsyncMock()
+ handler.transport.send_metrics = AsyncMock(return_value=False)
+
+ with caplog.at_level(logging.WARNING, logger="guard_agent"):
+ await handler._flush_metrics()
+
+ assert "requeued in memory (metrics) for retry" in caplog.text
+ assert "retained in Redis" not in caplog.text
+
`@pytest.mark.asyncio`
async def test_events_warning_with_redis_mentions_redis(🤖 Prompt for AI Agents |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: rennf93/guard-agent
Length of output: 6113
🏁 Script executed:
Repository: rennf93/guard-agent
Length of output: 8406
🏁 Script executed:
Repository: rennf93/guard-agent
Length of output: 14807
🏁 Script executed:
Repository: rennf93/guard-agent
Length of output: 37989
Base Redis retention on the drained keys.
After Redis initialization, either persistence helper can catch a failed Redis write and return
None. The item remains in memory without a Redis key, but the warning still claims Redis retention because the handler is attached. Pass the drained keys to the retention helpers and add the Redis text only when every item has a non-empty key.Suggested fix
🤖 Prompt for AI Agents