Files
kefu/deploy/ui-performance-20260916/payload/test_ui_performance.py
T
2026-09-21 10:34:06 +08:00

96 lines
5.3 KiB
Python

"""Prevent invisible-page work and unbounded UI event processing."""
import os,queue
os.environ.setdefault('QT_QPA_PLATFORM','offscreen')
from types import SimpleNamespace
from unittest import TestCase,mock
from wechat_gui_qt import MainWindow,SettingsPage
def snapshot_host(view):
text=lambda value:SimpleNamespace(text=lambda:value)
host=SimpleNamespace(_running=False,_status_key='stopped',_console_view=view,runtime_settings={},
business_page=SimpleNamespace(archive_search=text(''),active_archive_filter='全部'),
queue_page=SimpleNamespace(pending_states={},active_task_filter='全部'),
log_page=SimpleNamespace(event_search=text(''),active_event_filter='全部'),
_console_wecom_info=mock.Mock(return_value={'connected':False}),
_console_dpi_label=mock.Mock(return_value='100%'),
_console_idle_label=mock.Mock(return_value='5秒'),
_console_runtime_label=mock.Mock(return_value='00:00:00'),
_console_archive_filter_label=mock.Mock(return_value='全部会话'))
defaults={'people':[{'key':'one'}],'logs':[],'activities':[],'metrics':{},'journey':[],'task':None,
'journey_total':'','chain':[],'window_stats':[],'archives':[{'key':'archive'}],
'chat':[],'memory':{},'settle':{},'ai_state':{'name':'客服'},'automation_state':{'poll':2},
'system_state':{'scale':'自动','serverUrl':'http://example.invalid'},'log_detail':{}}
for name,value in defaults.items():setattr(host,'_console_'+name,mock.Mock(return_value=value))
host._console_sort_people=mock.Mock(side_effect=lambda people:people)
host._wechat_database_console_state=mock.Mock(return_value={'accounts':[]})
return host
class SnapshotPerformanceTest(TestCase):
def test_editing_pages_do_not_read_queues_archives_or_logs(self):
for view,key in [('ai','ai'),('automation','automation'),('system','system'),('wechatdb','wechatDb')]:
with self.subTest(view=view):
host=snapshot_host(view);data=MainWindow._console_snapshot(host)
self.assertIn(key,data)
for name in ['people','task','archives','chat','memory','logs','metrics']:
getattr(host,'_console_'+name).assert_not_called()
if view!='system':host._console_system_state.assert_not_called()
def test_each_page_receives_its_required_state(self):
required={'auto':['people','task','journey','windowStats','metrics'],
'queue':['people','task','chain','metrics'],
'archive':['archives','chat','memory','settle'],
'logs':['logs','logDetail','exceptions','chain','metrics'],
'ai':['ai'],'automation':['automation'],'system':['system'],'wechatdb':['wechatDb']}
for view,keys in required.items():
data=MainWindow._console_snapshot(snapshot_host(view))
for key in keys:self.assertIn(key,data,(view,key))
def test_system_cache_preserves_connection_fields_and_updates_scale(self):
host=snapshot_host('system');MainWindow._console_snapshot(host)
host._console_view='ai';host.runtime_settings={'scale_ratio':'200%'}
result=MainWindow._console_snapshot(host)
self.assertEqual(result['system']['serverUrl'],'http://example.invalid')
self.assertEqual(result['system']['scale'],'200%')
host._console_system_state.assert_called_once()
def test_live_queue_does_not_build_archive_or_settings_views(self):
host=snapshot_host('queue');data=MainWindow._console_snapshot(host)
self.assertEqual(data['selectedKey'],'one');self.assertTrue(data['people'][0]['active'])
for name in ['archives','chat','memory','ai_state','system_state','automation_state']:
getattr(host,'_console_'+name).assert_not_called()
host._wechat_database_console_state.assert_not_called()
class EventLoopPerformanceTest(TestCase):
def host(self,count):
events=queue.Queue()
for i in range(count):events.put(('log',str(i)))
return SimpleNamespace(_queue=events,_start_time=None,_running=False,
append_log=mock.Mock(),queue_timer=mock.Mock())
def test_large_event_burst_yields_after_64_and_keeps_order(self):
host=self.host(200)
with mock.patch('wechat_gui_qt.time.perf_counter',return_value=0):
MainWindow._process_queue(host)
self.assertEqual(host._queue.qsize(),136)
host.queue_timer.setInterval.assert_called_with(16)
for _ in range(3):MainWindow._process_queue(host)
self.assertTrue(host._queue.empty())
self.assertEqual([c.args[0] for c in host.append_log.call_args_list],[str(i) for i in range(200)])
host.queue_timer.setInterval.assert_called_with(140)
def test_time_budget_yields_even_when_message_limit_not_reached(self):
host=self.host(20)
with mock.patch('wechat_gui_qt.time.perf_counter',side_effect=[0,0.001,0.010]):
MainWindow._process_queue(host)
self.assertEqual(host.append_log.call_count,1)
self.assertEqual(host._queue.qsize(),19)
def test_manual_save_consumes_pending_native_autosave(self):
host=SimpleNamespace(save_timer=mock.Mock(),_set_save_status=mock.Mock(),saved=mock.Mock(),values=lambda:{'poll_interval':7})
SettingsPage._emit_save(host)
host.save_timer.stop.assert_called_once()
host.saved.emit.assert_called_once_with({'poll_interval':7})