Files
DashBoard/tests/test_app_factory.py
beabigegg 373a1f0f0e perf: 移除舊版 resource summary API 並加入 WIP DataFrame 記憶體快取
問題診斷:
- 舊版 /api/resource/summary API 使用慢速 SQL (JOIN + ROW_NUMBER),導致 55s 逾時
- 壓力測試持續呼叫此 API,佔滿所有 worker threads
- 每次 WIP API 請求都解析 14.8MB JSON,8 個並發請求造成 GIL 競爭

變更內容:
- 移除舊版 /api/resource/summary 路由和 query_resource_status_summary 函數
- 刪除未使用的 status_summary.sql
- 更新壓力測試和整合測試使用新版 /api/resource/status/summary
- 加入 ProcessLevelCache 類別實作 process-level DataFrame 快取 (30s TTL)
- 使用 double-check locking 確保只有一個 thread 解析 JSON

效能改善:
- 新版 API 使用 Redis 三層快取,回應時間 < 100ms
- Process-level 快取避免重複解析 14MB JSON,大幅改善並發效能

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:00:41 +08:00

55 lines
1.7 KiB
Python

import unittest
from mes_dashboard.app import create_app
from mes_dashboard.core.cache import NoOpCache
import mes_dashboard.core.database as db
class AppFactoryTests(unittest.TestCase):
def setUp(self):
db._ENGINE = None
def test_create_app_default_config(self):
app = create_app()
self.assertTrue(app.config.get("DEBUG"))
self.assertEqual(app.config.get("ENV"), "development")
self.assertIsInstance(app.extensions.get("cache"), NoOpCache)
def test_create_app_production_config(self):
app = create_app("production")
self.assertFalse(app.config.get("DEBUG"))
self.assertEqual(app.config.get("ENV"), "production")
def test_create_app_independent_instances(self):
app1 = create_app()
db._ENGINE = None
app2 = create_app()
self.assertIsNot(app1, app2)
def test_routes_registered(self):
app = create_app()
rules = {rule.rule for rule in app.url_map.iter_rules()}
expected = {
"/",
"/tables",
"/resource",
"/wip-overview",
"/wip-detail",
"/excel-query",
"/api/wip/overview/summary",
"/api/wip/overview/matrix",
"/api/wip/overview/hold",
"/api/wip/detail/<workcenter>",
"/api/wip/meta/workcenters",
"/api/wip/meta/packages",
"/api/resource/status/summary",
"/api/dashboard/kpi",
"/api/excel-query/upload",
}
missing = expected - rules
self.assertFalse(missing, f"Missing routes: {sorted(missing)}")
if __name__ == "__main__":
unittest.main()