feat: refresh model and voice test catalog with favicon

This commit is contained in:
AdamWen95
2026-10-20 11:06:52 +08:00
parent ae7c5bc967
commit 36c228544e
23 changed files with 1026 additions and 42 deletions
+43
View File
@@ -0,0 +1,43 @@
import hashlib
from pathlib import Path
import tempfile
import unittest
from console.settings import Settings
from console.store import Store
from console.catalog import discover
from deploy.refresh_catalog import refresh, restore
class CatalogRefreshTests(unittest.TestCase):
def test_refresh_preserves_options_and_history_and_restores_exactly(self):
with tempfile.TemporaryDirectory() as temporary:
base = Path(temporary); source = base/'source'; source.mkdir()
(source/'old.py').write_text('print(1)')
settings = Settings(base/'runtime', [{'id':'suite','path':str(source)}]); store = Store(settings)
discover(store)
old = store.scripts()[0]; old.update(enabled=True,status='ready',reason='')
old['config']['timeout_seconds'] = 457
store.save_script(old)
old_runs = store.runs()
(source/'old.py').write_text('print(5)')
(source/'new.py').write_text('print(2)'); (source/'blocked.py').write_text('print(3)')
(source/'support.py').write_text('print(4)')
settings.native_catalog['profiles'] = [
{'id':name,'source_group':'suite','entry':name+'.py','cwd':str(source),'interpreter':'/usr/bin/python3',
'user':'root','available':name!='blocked','unavailable_reason':'原服务预设已过期','parameters':[]}
for name in ('old','new','blocked')]
snapshot = base/'migration.json'
self.assertFalse(refresh(store, snapshot)['applied'])
self.assertFalse(snapshot.exists())
refresh(store, snapshot, True)
by_name = {s['name']:s for s in store.scripts()}
self.assertEqual(by_name['old.py']['config']['timeout_seconds'],457)
self.assertFalse(by_name['old.py']['enabled'])
self.assertEqual(by_name['old.py']['version'],2)
self.assertTrue(by_name['new.py']['enabled'])
self.assertFalse(by_name['blocked.py']['enabled'])
self.assertFalse(by_name['support.py']['enabled'])
self.assertEqual(store.runs(),old_runs)
self.assertEqual(refresh(store,base/'again.json',True)['changed'],0)
restore(store,snapshot)
self.assertEqual(store.scripts(),[old])
+69
View File
@@ -0,0 +1,69 @@
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
from pathlib import Path
import tempfile
import threading
import unittest
from unittest.mock import patch
from console.model_preflight import check_model
class ModelPreflightTests(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.root = Path(self.temp.name)
self.credential = self.root / 'vllm.env'
self.credential.write_text('VLLM_API_KEY="dummy-metadata-key"\n')
self.calls = []
self.status = 200
self.body = {'data': [{'id': 'current-model', 'max_model_len': 262144}]}
case = self
class Handler(BaseHTTPRequestHandler):
def log_message(self, *args): pass
def do_GET(self):
case.calls.append((self.path, self.headers.get('Authorization')))
self.send_response(case.status)
if case.status == 302:
self.send_header('Location', '/redirect-target')
self.end_headers()
self.wfile.write(json.dumps(case.body).encode())
self.server = HTTPServer(('127.0.0.1', 0), Handler)
self.thread = threading.Thread(target=self.server.serve_forever, daemon=True)
self.thread.start()
self.target = {'url': 'http://127.0.0.1:' + str(self.server.server_port), 'model': 'current-model'}
def tearDown(self):
self.server.shutdown(); self.server.server_close(); self.thread.join()
self.temp.cleanup()
def test_metadata_only_one_request_with_runtime_credentials(self):
result = check_model(self.target, [str(self.credential)])
self.assertTrue(result['ok'])
self.assertEqual(self.calls, [('/v1/models', 'Bearer dummy-metadata-key')])
self.assertNotIn('dummy-metadata-key', json.dumps(result))
def test_wrong_model_fails_even_when_port_is_open(self):
self.target['model'] = 'stale-model'
result = check_model(self.target, [str(self.credential)])
self.assertFalse(result['ok'])
self.assertIn('模型名称', result['message'])
def test_auth_failure_and_redirect_do_not_retry_or_leak(self):
for status in (401, 302):
self.status = status; self.calls.clear()
result = check_model(self.target, [str(self.credential)])
self.assertFalse(result['ok'])
self.assertEqual(len(self.calls), 1)
self.assertNotIn('dummy-metadata-key', json.dumps(result))
def test_external_address_rejected_before_network(self):
self.target['url'] = 'http://example.com'
with patch('console.model_preflight.urllib.request.build_opener') as build:
self.assertFalse(check_model(self.target, [])['ok'])
build.assert_not_called()
def test_malformed_or_oversize_metadata_is_not_success(self):
for body in ({'data': {}}, {'data': ['bad']}, {'data': [], 'padding': 'x' * 262145}):
self.body = body
self.assertFalse(check_model(self.target, [str(self.credential)])['ok'])
+59
View File
@@ -0,0 +1,59 @@
import json
from pathlib import Path
from types import SimpleNamespace
import unittest
import tempfile
from unittest.mock import patch
from console.native_container import command, cleanup
from console.native_io import read_secret_tables, SecretFilter
class NativeContainerTests(unittest.TestCase):
def test_registered_key_table_is_redacted_without_environment_injection(self):
with tempfile.TemporaryDirectory() as temporary:
path = Path(temporary) / 'keys.txt'
path.write_text('# local fixture\noperator dummy-audio-key scope\n')
values = read_secret_tables([{'path': str(path), 'key_column': 1}])
self.assertEqual(values, ['dummy-audio-key'])
self.assertNotIn(b'dummy-audio-key', SecretFilter(values).clean(b'header=dummy-audio-key'))
def setUp(self):
self.identity = 'a' * 32
self.profile = {'docker': {'image': 'sha256:' + 'b' * 64, 'mounts': [{'source': '/original/tests', 'target': '/t'}]},
'interpreter': '/opt/omni/bin/python'}
def test_fixed_image_readonly_sources_and_owned_output_without_gpu(self):
args = command(self.profile, Path('/original/tests/test_api.py'), ['x'], '/runs/' + self.identity, self.identity)
self.assertIn('xas.native-run=' + self.identity, args)
self.assertIn('type=bind,src=/original/tests,dst=/t,readonly', args)
self.assertIn('type=bind,src=/runs/' + self.identity + '/work,dst=/out', args)
self.assertEqual(args[-4:], [self.profile['docker']['image'], '-u', '/t/test_api.py', 'x'])
self.assertNotIn('--gpus', args)
self.assertIn('runc', args)
def test_cleanup_rejects_foreign_container(self):
inspected = SimpleNamespace(returncode=0, stdout=json.dumps([{'Name': '/adamwen-native-run-' + self.identity,
'Config': {'Labels': {'xas.native-run': 'other'}}}]), stderr='')
with patch('console.native_container.subprocess.run', return_value=inspected) as call:
with self.assertRaises(ValueError): cleanup(self.identity)
self.assertEqual(call.call_count, 1)
def test_daemon_error_is_not_treated_as_container_missing(self):
error = SimpleNamespace(returncode=1, stdout='', stderr='Cannot connect to Docker daemon')
with patch('console.native_container.subprocess.run', return_value=error):
with self.assertRaises(OSError): cleanup(self.identity)
def test_missing_owned_container_is_already_clean(self):
missing = SimpleNamespace(returncode=1, stdout='', stderr='error: no such object: adamwen-native-run-' + self.identity)
with patch('console.native_container.subprocess.run', return_value=missing) as call:
cleanup(self.identity)
self.assertEqual(call.call_count, 1)
def test_auto_removed_container_race_is_not_an_uncertain_cleanup(self):
container_id = 'c' * 64
inspected = SimpleNamespace(returncode=0, stdout=json.dumps([{'Id':container_id,
'Name':'/adamwen-native-run-' + self.identity,'Config':{'Labels':{'xas.native-run':self.identity}}}]),stderr='')
gone = SimpleNamespace(returncode=1,stdout='',stderr='Error: No such container: ' + container_id)
with patch('console.native_container.subprocess.run',side_effect=[inspected,gone,gone]) as call:
cleanup(self.identity)
self.assertEqual(call.call_args_list[1].args[0][-1],container_id)