test_real_redis.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. from datetime import UTC, datetime
  2. import pytest
  3. from redis import Redis
  4. from app.commands.reset_cache import clear_project_cache
  5. from app.core.config import Settings
  6. from app.harness.events import RuntimeEvent
  7. from app.infrastructure.redis.agent_state import RedisAgentStateStore
  8. from app.infrastructure.redis.keys import RedisKeyBuilder
  9. settings = Settings()
  10. pytestmark = pytest.mark.skipif(
  11. settings.app_env != "test" or not settings.redis_prefix.startswith("ins:s1:test:"),
  12. reason="真实Redis集成测试只允许使用白名单测试前缀",
  13. )
  14. def test_real_redis_prefix_round_trip_and_scoped_cleanup() -> None:
  15. client = Redis.from_url(settings.redis_url, decode_responses=True)
  16. keys = RedisKeyBuilder(settings.redis_prefix)
  17. session_key = keys.auth_session("integration-session")
  18. product_key = keys.product_cache("integration-products")
  19. adjacent_key = "ins:s1:test:adjacent:sentinel"
  20. try:
  21. client.set(session_key, "active", ex=60)
  22. client.set(product_key, "cached", ex=60)
  23. client.set(adjacent_key, "keep", ex=60)
  24. assert client.get(session_key) == "active"
  25. assert client.get(product_key) == "cached"
  26. assert clear_project_cache(settings) == 2
  27. assert client.get(session_key) is None
  28. assert client.get(product_key) is None
  29. assert client.get(adjacent_key) == "keep"
  30. finally:
  31. client.delete(session_key, product_key, adjacent_key)
  32. client.close()
  33. def test_real_redis_agent_hot_state_rate_limit_and_events() -> None:
  34. store = RedisAgentStateStore(settings)
  35. keys = RedisKeyBuilder(settings.redis_prefix)
  36. thread_id = "integration-thread"
  37. run_id = "integration-run"
  38. principal_id = "integration-user"
  39. thread_key = keys.agent_thread_hot(thread_id)
  40. rate_key = keys.agent_rate(principal_id)
  41. events_key = keys.agent_run_events(run_id)
  42. client = Redis.from_url(settings.redis_url, decode_responses=True)
  43. try:
  44. store.touch_thread(
  45. thread_id,
  46. owner_type="H5_USER",
  47. owner_id=principal_id,
  48. persona="customer",
  49. )
  50. assert store.allow_request(principal_id)
  51. store.append_event(
  52. RuntimeEvent(
  53. event="run.started",
  54. run_id=run_id,
  55. sequence=1,
  56. occurred_at=datetime.now(UTC),
  57. data={"persona": "customer"},
  58. )
  59. )
  60. assert client.ttl(thread_key) > 0
  61. assert client.ttl(rate_key) > 0
  62. events = store.list_events(run_id)
  63. assert len(events) == 1
  64. assert events[0].event == "run.started"
  65. assert client.ttl(events_key) > 0
  66. finally:
  67. client.delete(thread_key, rate_key, events_key)
  68. store.close()
  69. client.close()