chore: finalize vite migration hardening and archive openspec changes
This commit is contained in:
@@ -4,9 +4,10 @@
|
||||
Tests aggregation, status classification, and cache query functionality.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
import json
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
import json
|
||||
import pandas as pd
|
||||
|
||||
|
||||
class TestClassifyStatus:
|
||||
@@ -297,12 +298,17 @@ class TestGetEquipmentStatusById:
|
||||
"""Test get_equipment_status_by_id function."""
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def reset_modules(self):
|
||||
"""Reset module state before each test."""
|
||||
import mes_dashboard.core.redis_client as rc
|
||||
rc._REDIS_CLIENT = None
|
||||
yield
|
||||
rc._REDIS_CLIENT = None
|
||||
def reset_modules(self):
|
||||
"""Reset module state before each test."""
|
||||
import mes_dashboard.core.redis_client as rc
|
||||
import mes_dashboard.services.realtime_equipment_cache as eq
|
||||
rc._REDIS_CLIENT = None
|
||||
eq._equipment_status_cache.invalidate("equipment_status_all")
|
||||
eq._invalidate_equipment_status_lookup()
|
||||
yield
|
||||
rc._REDIS_CLIENT = None
|
||||
eq._equipment_status_cache.invalidate("equipment_status_all")
|
||||
eq._invalidate_equipment_status_lookup()
|
||||
|
||||
def test_returns_none_when_redis_unavailable(self):
|
||||
"""Test returns None when Redis client unavailable."""
|
||||
@@ -350,12 +356,17 @@ class TestGetEquipmentStatusByIds:
|
||||
"""Test get_equipment_status_by_ids function."""
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def reset_modules(self):
|
||||
"""Reset module state before each test."""
|
||||
import mes_dashboard.core.redis_client as rc
|
||||
rc._REDIS_CLIENT = None
|
||||
yield
|
||||
rc._REDIS_CLIENT = None
|
||||
def reset_modules(self):
|
||||
"""Reset module state before each test."""
|
||||
import mes_dashboard.core.redis_client as rc
|
||||
import mes_dashboard.services.realtime_equipment_cache as eq
|
||||
rc._REDIS_CLIENT = None
|
||||
eq._equipment_status_cache.invalidate("equipment_status_all")
|
||||
eq._invalidate_equipment_status_lookup()
|
||||
yield
|
||||
rc._REDIS_CLIENT = None
|
||||
eq._equipment_status_cache.invalidate("equipment_status_all")
|
||||
eq._invalidate_equipment_status_lookup()
|
||||
|
||||
def test_returns_empty_for_empty_input(self):
|
||||
"""Test returns empty list for empty input."""
|
||||
@@ -401,12 +412,17 @@ class TestGetAllEquipmentStatus:
|
||||
"""Test get_all_equipment_status function."""
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def reset_modules(self):
|
||||
"""Reset module state before each test."""
|
||||
import mes_dashboard.core.redis_client as rc
|
||||
rc._REDIS_CLIENT = None
|
||||
yield
|
||||
rc._REDIS_CLIENT = None
|
||||
def reset_modules(self):
|
||||
"""Reset module state before each test."""
|
||||
import mes_dashboard.core.redis_client as rc
|
||||
import mes_dashboard.services.realtime_equipment_cache as eq
|
||||
rc._REDIS_CLIENT = None
|
||||
eq._equipment_status_cache.invalidate("equipment_status_all")
|
||||
eq._invalidate_equipment_status_lookup()
|
||||
yield
|
||||
rc._REDIS_CLIENT = None
|
||||
eq._equipment_status_cache.invalidate("equipment_status_all")
|
||||
eq._invalidate_equipment_status_lookup()
|
||||
|
||||
def test_returns_empty_when_redis_unavailable(self):
|
||||
"""Test returns empty list when Redis unavailable."""
|
||||
@@ -449,7 +465,7 @@ class TestGetAllEquipmentStatus:
|
||||
assert result[1]['RESOURCEID'] == 'R002'
|
||||
|
||||
|
||||
class TestGetEquipmentStatusCacheStatus:
|
||||
class TestGetEquipmentStatusCacheStatus:
|
||||
"""Test get_equipment_status_cache_status function."""
|
||||
|
||||
@pytest.fixture
|
||||
@@ -489,6 +505,44 @@ class TestGetEquipmentStatusCacheStatus:
|
||||
from mes_dashboard.services.realtime_equipment_cache import get_equipment_status_cache_status
|
||||
result = get_equipment_status_cache_status()
|
||||
|
||||
assert result['enabled'] is True
|
||||
assert result['loaded'] is True
|
||||
assert result['count'] == 1000
|
||||
assert result['enabled'] is True
|
||||
assert result['loaded'] is True
|
||||
assert result['count'] == 1000
|
||||
|
||||
|
||||
class TestEquipmentProcessLevelCache:
|
||||
"""Test bounded process-level cache behavior for equipment status."""
|
||||
|
||||
def test_lru_eviction_prefers_recent_keys(self):
|
||||
import mes_dashboard.services.realtime_equipment_cache as eq
|
||||
|
||||
cache = eq._ProcessLevelCache(ttl_seconds=60, max_size=2)
|
||||
cache.set("a", [{"RESOURCEID": "R001"}])
|
||||
cache.set("b", [{"RESOURCEID": "R002"}])
|
||||
assert cache.get("a") is not None # refresh recency
|
||||
cache.set("c", [{"RESOURCEID": "R003"}]) # should evict "b"
|
||||
|
||||
assert cache.get("b") is None
|
||||
assert cache.get("a") is not None
|
||||
assert cache.get("c") is not None
|
||||
|
||||
def test_global_equipment_cache_uses_bounded_config(self):
|
||||
import mes_dashboard.services.realtime_equipment_cache as eq
|
||||
|
||||
assert eq.EQUIPMENT_PROCESS_CACHE_MAX_SIZE >= 1
|
||||
assert eq._equipment_status_cache.max_size == eq.EQUIPMENT_PROCESS_CACHE_MAX_SIZE
|
||||
|
||||
|
||||
class TestSharedQueryFragments:
|
||||
"""Test shared SQL fragment governance for equipment cache."""
|
||||
|
||||
def test_equipment_load_uses_shared_sql_fragment(self):
|
||||
import mes_dashboard.services.realtime_equipment_cache as eq
|
||||
from mes_dashboard.services.sql_fragments import EQUIPMENT_STATUS_SELECT_SQL
|
||||
|
||||
mock_df = pd.DataFrame([{"RESOURCEID": "R001", "EQUIPMENTID": "EQ-01"}])
|
||||
with patch.object(eq, "read_sql_df", return_value=mock_df) as mock_read:
|
||||
eq._load_equipment_status_from_oracle()
|
||||
|
||||
sql = mock_read.call_args[0][0]
|
||||
assert sql.strip() == EQUIPMENT_STATUS_SELECT_SQL.strip()
|
||||
|
||||
Reference in New Issue
Block a user