Files
kefu/deploy/recognition-audit-20260916/knowledge_runner.py
T
2026-09-21 10:34:06 +08:00

58 lines
2.7 KiB
Python

"""Run knowledge tests with isolated app data and external networking disabled."""
import contextlib
import importlib
import io
import json
import os
from pathlib import Path
import socket
import sys
import tempfile
import threading
import time
import unittest
from unittest import mock
root = Path(sys.argv[1]).resolve()
output = Path(sys.argv[2]).resolve()
modules = sys.argv[3:] or ['test_knowledge','test_knowledge_search','test_knowledge_review','test_knowledge_tasks','test_knowledge_model_output','test_model_gateway']
sys.path.insert(0, str(root))
sys.path.insert(1, str(Path(__file__).parent))
os.environ['QT_QPA_PLATFORM'] = 'offscreen'
os.environ['KNOWLEDGE_QDRANT_URL'] = ''
os.environ['KNOWLEDGE_EMBEDDING_URL'] = ''
os.environ['KNOWLEDGE_EMBEDDING_MODEL'] = ''
import runtime_paths
original_connect, original_pair = socket.socket.connect, socket.socketpair
internal = threading.local()
def connect(sock, address):
if getattr(internal, 'wakeup', False):
return original_connect(sock, address)
raise AssertionError('External network blocked in audit')
def socketpair(*args, **kwargs):
internal.wakeup = True
try:
return original_pair(*args, **kwargs)
finally:
internal.wakeup = False
with tempfile.TemporaryDirectory(prefix='recognition-knowledge-') as directory, contextlib.ExitStack() as stack:
stack.enter_context(mock.patch.object(runtime_paths,'application_data_dir',return_value=Path(directory)))
stack.enter_context(mock.patch.object(socket.socket,'connect',connect))
stack.enter_context(mock.patch.object(socket,'socketpair',socketpair))
stack.enter_context(mock.patch.object(socket.socket,'connect_ex',side_effect=AssertionError('External network blocked in audit')))
stream = io.StringIO()
with contextlib.redirect_stdout(stream), contextlib.redirect_stderr(stream):
suite = unittest.defaultTestLoader.loadTestsFromNames(modules)
start = time.monotonic()
result = unittest.TextTestRunner(stream=stream, verbosity=2).run(suite)
output.parent.mkdir(parents=True,exist_ok=True)
output.with_suffix('.log').write_text(stream.getvalue(),encoding='utf-8')
data = {'root':str(root),'modules':modules,'tests':result.testsRun,'failures':len(result.failures),
'errors':len(result.errors),'skipped':len(result.skipped),'elapsed_seconds':round(time.monotonic()-start,2)}
output.with_suffix('.json').write_text(json.dumps(data,ensure_ascii=False,indent=2),encoding='utf-8')
print(json.dumps(data,ensure_ascii=False))
if not result.wasSuccessful():
for test, error in result.failures+result.errors:
print(str(test), error)
sys.exit(0 if result.wasSuccessful() else 1)