feat: initialize XAS test console with native execution

This commit is contained in:
AdamWen95
2026-10-14 09:38:58 +08:00
commit 438844b01a
83 changed files with 9334 additions and 0 deletions
+126
View File
@@ -0,0 +1,126 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
import json
from pathlib import Path
import tempfile
import threading
import unittest
import urllib.error
import urllib.request
from console.artifacts import Collector
from console.job_main import BudgetRelay
from console.settings import Settings
class OutputTests(unittest.TestCase):
def test_final_file_log_drain_includes_fast_script_tail_larger_than_one_chunk(self):
with tempfile.TemporaryDirectory() as temp:
root = Path(temp)
logs, run = root / "logs", root / "run"
logs.mkdir()
run.mkdir()
collector = Collector(Settings(root, []), run, [str(logs)])
payload = b"file log\n" * 10000
(logs / "new.log").write_bytes(payload)
parts = []
collector.finish_follow(parts.append)
self.assertEqual(b"".join(parts), "\n[文件日志 new.log]\n".encode() + payload)
self.assertEqual(collector.follow(parts.append), 0)
def test_proxy_does_not_redirect_credentials_or_add_requests(self):
seen = []
class Redirect(BaseHTTPRequestHandler):
def log_message(self, *args):
pass
def do_GET(self):
seen.append(self.path)
self.send_response(302)
self.send_header("Location", "/unexpected")
self.end_headers()
upstream = HTTPServer(("127.0.0.1", 0), Redirect)
relay = BudgetRelay(("127.0.0.1", 0), f"http://127.0.0.1:{upstream.server_port}", "test-only-credential")
threads = [threading.Thread(target=s.serve_forever, daemon=True) for s in (upstream, relay)]
for thread in threads:
thread.start()
try:
with self.assertRaises(urllib.error.HTTPError) as rejected:
urllib.request.urlopen(f"http://127.0.0.1:{relay.server_port}/v1/models", timeout=5)
self.assertEqual(rejected.exception.code, 302)
self.assertEqual(seen, ["/v1/models"])
self.assertEqual(relay.gets, 1)
finally:
for server in (relay, upstream):
server.shutdown()
server.server_close()
for thread in threads:
thread.join()
def test_only_changed_external_outputs_are_archived_and_originals_preserved(self):
with tempfile.TemporaryDirectory() as temp:
root = Path(temp)
output, run = root / "original_logs", root / "run"
output.mkdir()
run.mkdir()
(run / "work").mkdir()
old = output / "old.json"
old.write_text('{"old":true}')
log = output / "current.log"
log.write_bytes(b"previous\n")
collector = Collector(Settings(root, []), run, [str(output)])
with log.open("ab") as handle:
handle.write("新日志\n".encode())
messages = []
collector.follow(messages.append)
collector.follow(messages.append)
self.assertEqual(len(messages), 1)
self.assertIn("新日志", messages[0].decode())
self.assertNotIn("previous", messages[0].decode())
(run / "work/result.json").write_text('{"ok":true}')
items = collector.collect()
self.assertEqual({i["name"] for i in items}, {"current.log", "result.json"})
self.assertEqual(old.read_text(), '{"old":true}')
self.assertTrue(log.exists())
log.write_text("overwritten later")
archived = next(i for i in items if i["name"] == "current.log")
self.assertIn("新日志", (run / "artifacts" / archived["id"]).read_text(encoding="utf-8"))
def test_model_proxy_budget_and_auth_are_per_run_without_retry(self):
requests = []
class Upstream(BaseHTTPRequestHandler):
def log_message(self, *args):
pass
def do_GET(self):
requests.append((self.path, self.headers.get("Authorization")))
self.send_response(200)
self.end_headers()
self.wfile.write(b'{"data":[]}')
def do_POST(self):
self.rfile.read(int(self.headers["Content-Length"]))
requests.append((self.path, self.headers.get("Authorization")))
self.send_response(503)
self.end_headers()
upstream = HTTPServer(("127.0.0.1", 0), Upstream)
relay = BudgetRelay(("127.0.0.1", 0), f"http://127.0.0.1:{upstream.server_port}", "test-only-credential")
threads = [threading.Thread(target=s.serve_forever, daemon=True) for s in (upstream, relay)]
for t in threads:
t.start()
url = f"http://127.0.0.1:{relay.server_port}"
try:
with urllib.request.urlopen(url + "/v1/models", timeout=5) as response:
self.assertEqual(response.status, 200)
with self.assertRaises(urllib.error.HTTPError) as rejected:
urllib.request.urlopen(url + "/v1/models", timeout=5)
self.assertEqual(rejected.exception.code, 403)
data = json.dumps({"model": "deepseek-v4.1-flash", "max_tokens": 512}).encode()
for i in range(4):
with self.assertRaises(urllib.error.HTTPError) as rejected:
urllib.request.urlopen(url + "/v1/chat/completions", data, timeout=5)
self.assertEqual(rejected.exception.code, 503 if i < 3 else 403)
self.assertEqual(len(requests), 4)
self.assertTrue(all(auth == "Bearer test-only-credential" for _, auth in requests))
self.assertNotIn("test-only-credential", json.dumps(relay.records))
finally:
for server in (relay, upstream):
server.shutdown()
server.server_close()
for thread in threads:
thread.join()