feat: add Quant OS public status console
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
PROJECT = Path(__file__).resolve().parents[1]
|
||||
BUILDER_PATH = PROJECT / "tools" / "build_public_status.py"
|
||||
OUTPUT_PATH = PROJECT / "status" / "status-data.js"
|
||||
INDEX_PATH = PROJECT / "status" / "index.html"
|
||||
PREFIX = "window.QUANT_OS_PUBLIC_STATUS = "
|
||||
|
||||
|
||||
def _load_builder():
|
||||
spec = importlib.util.spec_from_file_location("build_public_status", BUILDER_PATH)
|
||||
if spec is None or spec.loader is None:
|
||||
raise RuntimeError("cannot import public status builder")
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
def _read_payload(path=OUTPUT_PATH):
|
||||
content = path.read_text(encoding="utf-8")
|
||||
lines = content.splitlines()
|
||||
if not lines or not lines[0].startswith("// Generated by"):
|
||||
raise AssertionError("generated header is missing")
|
||||
assignment = "\n".join(lines[1:])
|
||||
if not assignment.startswith(PREFIX) or not assignment.endswith(";"):
|
||||
raise AssertionError("unexpected JavaScript wrapper")
|
||||
return json.loads(assignment[len(PREFIX) : -1])
|
||||
|
||||
|
||||
class PublicStatusTests(unittest.TestCase):
|
||||
def test_committed_status_data_has_no_drift(self):
|
||||
result = subprocess.run(
|
||||
[sys.executable, str(BUILDER_PATH), "--check"],
|
||||
cwd=PROJECT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
payload = _read_payload()
|
||||
self.assertEqual(payload["claim"]["status"], "NOT_BASELINE_60")
|
||||
self.assertFalse(payload["claim"]["releaseVerified"])
|
||||
self.assertFalse(payload["claim"]["liveReady"])
|
||||
self.assertEqual(payload["claim"]["gatesPassed"], 0)
|
||||
self.assertEqual(payload["claim"]["gatesTotal"], 10)
|
||||
self.assertTrue(all(gate["status"] == "not_passed" for gate in payload["gates"]))
|
||||
|
||||
def test_public_payload_is_deliberately_non_secret_and_non_local(self):
|
||||
payload = _read_payload()
|
||||
encoded = json.dumps(payload, ensure_ascii=False, sort_keys=True)
|
||||
self.assertNotRegex(
|
||||
encoded,
|
||||
re.compile(r"/(?:Users|home|root|private|var|tmp)/|[A-Za-z]:[\\/]"),
|
||||
)
|
||||
self.assertNotIn("RELEASE_VERIFIED", encoded)
|
||||
self.assertNotIn("LIVE_READY", encoded)
|
||||
lowered = encoded.lower()
|
||||
for marker in (
|
||||
"password",
|
||||
"passwd",
|
||||
"api_key",
|
||||
"private_key",
|
||||
"userdata_path",
|
||||
):
|
||||
self.assertNotIn(marker, lowered)
|
||||
for evidence in payload["evidence"]:
|
||||
self.assertFalse(Path(evidence["path"]).is_absolute())
|
||||
self.assertNotIn("..", Path(evidence["path"]).parts)
|
||||
|
||||
def test_static_page_has_fail_closed_fallback_and_no_local_paths(self):
|
||||
page = INDEX_PATH.read_text(encoding="utf-8")
|
||||
self.assertIn('src="./status-data.js"', page)
|
||||
self.assertGreaterEqual(page.count("STATUS DATA UNAVAILABLE"), 2)
|
||||
self.assertIn("NOT_BASELINE_60", page)
|
||||
self.assertIn("0 / 10", page)
|
||||
self.assertIn("validatePublicData", page)
|
||||
self.assertIn("platform.limitations", page)
|
||||
self.assertNotIn("platform.missingReleaseEvidence", page)
|
||||
self.assertNotRegex(
|
||||
page,
|
||||
re.compile(
|
||||
r"(?:(?<=^)|(?<=[\s\"'=:(]))"
|
||||
r"(?:/(?:Users|home|root|private|var|tmp)/|[A-Za-z]:[\\/])"
|
||||
),
|
||||
)
|
||||
self.assertNotIn("quant-os/artifacts", page)
|
||||
self.assertNotIn("quant-os/data", page)
|
||||
for tag in re.findall(r"<a\\b[^>]*target=\"_blank\"[^>]*>", page):
|
||||
self.assertIn('rel="noopener noreferrer"', tag)
|
||||
|
||||
def test_models_and_platforms_preserve_evidence_boundaries(self):
|
||||
payload = _read_payload()
|
||||
models = {model["id"]: model for model in payload["models"]}
|
||||
self.assertEqual(
|
||||
set(models),
|
||||
{"portable-momentum-v1", "ridge-challenger", "alpha158-lightgbm"},
|
||||
)
|
||||
self.assertFalse(models["portable-momentum-v1"]["releaseVerified"])
|
||||
self.assertFalse(models["ridge-challenger"]["investmentValueClaim"])
|
||||
self.assertFalse(models["alpha158-lightgbm"]["investmentValueClaim"])
|
||||
self.assertIn("synthetic", models["ridge-challenger"]["role"])
|
||||
self.assertIn("synthetic", models["alpha158-lightgbm"]["limitations"][0])
|
||||
|
||||
platforms = {platform["name"]: platform for platform in payload["platforms"]}
|
||||
self.assertEqual(platforms["JoinQuant hosted bundle"]["status"], "real_runtime")
|
||||
self.assertEqual(platforms["QMT built-in bundle"]["status"], "implemented")
|
||||
self.assertFalse(platforms["XtTrader read-only shadow"]["liveReady"])
|
||||
self.assertIn("fake", platforms["XtTrader read-only shadow"]["claim"].lower())
|
||||
|
||||
def test_freshness_uses_daily_bars_not_the_later_trade_calendar(self):
|
||||
payload = _read_payload()
|
||||
freshness = {item["id"]: item for item in payload["freshness"]}
|
||||
self.assertEqual(freshness["project-audit"]["value"], "2026-07-26")
|
||||
self.assertEqual(
|
||||
freshness["joinquant-hosted-market-window"]["marketDataThrough"],
|
||||
"2024-12-31",
|
||||
)
|
||||
|
||||
tushare = freshness["tushare-daily-market-data"]
|
||||
self.assertEqual(tushare["completedPartitions"], 35)
|
||||
self.assertEqual(tushare["plannedPartitions"], 428)
|
||||
self.assertAlmostEqual(tushare["completionRatio"], 35 / 428, places=6)
|
||||
self.assertEqual(tushare["marketDataThrough"], "1993-10-29")
|
||||
self.assertFalse(tushare["productionReady"])
|
||||
source = (PROJECT / "docs" / "TUSHARE_LOCAL_DATA.md").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
self.assertRegex(source, r"`trade_cal`.*2026")
|
||||
self.assertNotIn("2026", tushare["marketDataThrough"])
|
||||
self.assertIn("daily", tushare["semantics"])
|
||||
|
||||
self.assertEqual(freshness["jqdata-real-snapshot"]["value"], "N/A")
|
||||
self.assertEqual(freshness["jqdata-real-snapshot"]["status"], "blocked")
|
||||
self.assertIsNone(
|
||||
freshness["qmt-broker-real-runtime"]["lastRealRuntimeAt"]
|
||||
)
|
||||
self.assertEqual(
|
||||
freshness["qmt-broker-real-runtime"]["status"], "blocked"
|
||||
)
|
||||
|
||||
def test_explicit_timestamp_build_is_deterministic(self):
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
first = Path(temp_dir) / "first.js"
|
||||
second = Path(temp_dir) / "second.js"
|
||||
command = [
|
||||
sys.executable,
|
||||
str(BUILDER_PATH),
|
||||
"--generated-at",
|
||||
"2026-07-26T08:09:10+08:00",
|
||||
]
|
||||
subprocess.run(
|
||||
[*command, "--output", str(first)],
|
||||
cwd=PROJECT,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
subprocess.run(
|
||||
[*command, "--output", str(second)],
|
||||
cwd=PROJECT,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertEqual(first.read_bytes(), second.read_bytes())
|
||||
payload = _read_payload(first)
|
||||
self.assertEqual(payload["generatedAt"], "2026-07-26T00:09:10Z")
|
||||
self.assertEqual(payload["generatedAtSource"], "argument")
|
||||
|
||||
def test_source_date_epoch_controls_timestamp(self):
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
output = Path(temp_dir) / "epoch.js"
|
||||
environment = dict(os.environ)
|
||||
environment["SOURCE_DATE_EPOCH"] = "0"
|
||||
result = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(BUILDER_PATH),
|
||||
"--output",
|
||||
str(output),
|
||||
],
|
||||
cwd=PROJECT,
|
||||
env=environment,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
payload = _read_payload(output)
|
||||
self.assertEqual(payload["generatedAt"], "1970-01-01T00:00:00Z")
|
||||
self.assertEqual(payload["generatedAtSource"], "source_date_epoch")
|
||||
|
||||
def test_builder_rejects_unearned_positive_claim(self):
|
||||
module = _load_builder()
|
||||
scorecard = {
|
||||
"claim_policy": {
|
||||
"baseline_threshold": 60,
|
||||
"current_claim": "BASELINE_60",
|
||||
},
|
||||
"current_delivery": {"score": 59},
|
||||
"gates": [{"id": "G1", "status": "not_passed"}],
|
||||
}
|
||||
with self.assertRaises(module.PublicStatusError):
|
||||
module._validate_claim(scorecard)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user