Files
group_xinghuo_jinrong/tests/test_wave6_analyst_cache.py
T
zhanghongyu_0626 ddcf53cfa8 feat(template): Implement template caching and SQL rendering for enhanced query handling
- Introduced `TemplateService` for managing SQL templates, allowing for parameterized queries based on user input.
- Added functionality to automatically reload templates upon asset creation in `analyst.py`.
- Enhanced `CacheService` to support table generation bumping, ensuring cache invalidation on data changes.
- Updated `RiskRepository` and `GatewayRepository` to trigger cache invalidation for relevant operations.
- Expanded `analyst_schemas.py` to include new fields for template tracking in response metadata.
- Created seed SQL script for populating initial templates and added unit tests for template rendering logic.

This update significantly improves the efficiency of query handling by leveraging SQL templates, reducing reliance on LLM for common queries.
2026-09-10 15:22:07 +08:00

82 lines
3.3 KiB
Python

"""cache_service 缓存单元测试(内存后端,无需 Redis)。"""
import time
import unittest
from app.service.cache_service import CacheService, InMemoryBackend
class TestCacheService(unittest.TestCase):
def setUp(self):
self.svc = CacheService(backend=InMemoryBackend())
def test_sql_hash_deterministic(self):
self.assertEqual(self.svc.sql_hash("SELECT 1"), self.svc.sql_hash("SELECT 1"))
self.assertNotEqual(self.svc.sql_hash("SELECT 1"), self.svc.sql_hash("SELECT 2"))
def test_permission_fingerprint_differs_by_scope(self):
a = self.svc.permission_fingerprint("S1", "assigned", ["CUST-1"])
b = self.svc.permission_fingerprint("S1", "assigned", ["CUST-2"])
self.assertNotEqual(a, b)
def test_ttl_layering(self):
self.assertEqual(self.svc.ttl_for(["core_trade"]), 5 * 60)
self.assertEqual(self.svc.ttl_for(["risk_alert"]), 60 * 60)
self.assertEqual(self.svc.ttl_for(["core_customer"]), 24 * 60 * 60)
def test_roundtrip(self):
fp = self.svc.permission_fingerprint("S1", "full")
sql = "SELECT COUNT(*) FROM core_customer"
tables = ["core_customer"]
self.assertIsNone(self.svc.get_result(fp, sql, tables))
self.svc.set_result(fp, sql, {"cnt": 33}, tables)
self.assertEqual(self.svc.get_result(fp, sql, tables), {"cnt": 33})
def test_invalidate(self):
fp = self.svc.permission_fingerprint("S1", "full")
sql = "SELECT 1 FROM core_customer"
tables = ["core_customer"]
self.svc.set_result(fp, sql, {"x": 1}, tables)
self.svc.invalidate_by_sql(fp, sql, tables)
self.assertIsNone(self.svc.get_result(fp, sql, tables))
def test_invalidate_tables_bumps_generation(self):
fp = self.svc.permission_fingerprint("S1", "full")
sql = "SELECT COUNT(*) FROM core_trade"
tables = ["core_trade"]
self.svc.set_result(fp, sql, {"cnt": 1}, tables)
self.assertEqual(self.svc.get_result(fp, sql, tables), {"cnt": 1})
self.svc.invalidate_tables(["core_trade"])
self.assertIsNone(self.svc.get_result(fp, sql, tables))
self.svc.set_result(fp, sql, {"cnt": 2}, tables)
self.assertEqual(self.svc.get_result(fp, sql, tables), {"cnt": 2})
def test_invalidate_tables_skips_unrelated(self):
fp = self.svc.permission_fingerprint("S1", "full")
sql = "SELECT COUNT(*) FROM core_customer"
tables = ["core_customer"]
self.svc.set_result(fp, sql, {"cnt": 9}, tables)
self.svc.invalidate_tables(["core_trade"])
self.assertEqual(self.svc.get_result(fp, sql, tables), {"cnt": 9})
def test_inmemory_expiry(self):
b = InMemoryBackend()
b.set("k", "v", ttl=1)
self.assertEqual(b.get("k"), "v")
time.sleep(1.2)
self.assertIsNone(b.get("k"))
def test_bump_analyst_cache_helper(self):
from app.service import analyst_cache_invalidate
analyst_cache_invalidate._svc = self.svc
fp = self.svc.permission_fingerprint("S1", "full")
sql = "SELECT COUNT(*) FROM core_trade"
tables = ["core_trade"]
self.svc.set_result(fp, sql, {"cnt": 1}, tables)
analyst_cache_invalidate.bump_analyst_cache_for_trade()
self.assertIsNone(self.svc.get_result(fp, sql, tables))
if __name__ == "__main__":
unittest.main()