feat: add Quant OS A-share baseline
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
import os
|
||||
import stat
|
||||
import tempfile
|
||||
import unittest
|
||||
from contextlib import redirect_stderr
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
|
||||
from tools.qmt_shadow_plan import (
|
||||
_load_existing_account_hash_key,
|
||||
_load_or_create_account_hash_key,
|
||||
build_parser,
|
||||
)
|
||||
|
||||
|
||||
class QmtShadowToolTests(unittest.TestCase):
|
||||
def test_account_hash_key_is_created_once_with_private_permissions(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
path = Path(directory) / "private" / "account-hash.key"
|
||||
first = _load_or_create_account_hash_key(path)
|
||||
second = _load_or_create_account_hash_key(path)
|
||||
self.assertEqual(first, second)
|
||||
self.assertEqual(len(first), 32)
|
||||
if os.name != "nt":
|
||||
self.assertEqual(
|
||||
stat.S_IMODE(path.stat().st_mode),
|
||||
0o600,
|
||||
)
|
||||
|
||||
def test_short_account_hash_key_is_rejected(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
path = Path(directory) / "account-hash.key"
|
||||
path.write_bytes(b"too-short")
|
||||
path.chmod(0o600)
|
||||
with self.assertRaisesRegex(ValueError, "at least 32 bytes"):
|
||||
_load_or_create_account_hash_key(path)
|
||||
|
||||
def test_verify_key_loader_never_creates_missing_key(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
path = Path(directory) / "missing-account-hash.key"
|
||||
with self.assertRaisesRegex(
|
||||
ValueError, "does not exist"
|
||||
):
|
||||
_load_existing_account_hash_key(path)
|
||||
self.assertFalse(path.exists())
|
||||
|
||||
def test_existing_parent_permissions_are_not_changed(self):
|
||||
if os.name == "nt":
|
||||
self.skipTest("POSIX permission invariant")
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
parent = Path(directory) / "shared-parent"
|
||||
parent.mkdir(mode=0o755)
|
||||
parent.chmod(0o755)
|
||||
_load_or_create_account_hash_key(parent / "account-hash.key")
|
||||
self.assertEqual(
|
||||
stat.S_IMODE(parent.stat().st_mode),
|
||||
0o755,
|
||||
)
|
||||
|
||||
def test_cli_rejects_widened_safety_thresholds(self):
|
||||
base = [
|
||||
"plan",
|
||||
"--decision",
|
||||
"decision-manifest.json",
|
||||
"--output",
|
||||
"shadow-output",
|
||||
]
|
||||
for option, value in (
|
||||
("--max-query-duration-seconds", "10.0001"),
|
||||
("--market-value-tolerance", "1.0001"),
|
||||
):
|
||||
with self.subTest(option=option), redirect_stderr(StringIO()):
|
||||
with self.assertRaises(SystemExit):
|
||||
build_parser().parse_args(base + [option, value])
|
||||
|
||||
def test_cli_accepts_only_equal_or_stricter_thresholds(self):
|
||||
parsed = build_parser().parse_args(
|
||||
[
|
||||
"plan",
|
||||
"--decision",
|
||||
"decision-manifest.json",
|
||||
"--output",
|
||||
"shadow-output",
|
||||
"--max-query-duration-seconds",
|
||||
"5",
|
||||
"--market-value-tolerance",
|
||||
"0.5",
|
||||
]
|
||||
)
|
||||
self.assertEqual(parsed.max_query_duration_seconds, 5.0)
|
||||
self.assertEqual(parsed.market_value_tolerance, 0.5)
|
||||
|
||||
def test_cli_verify_requires_original_decision(self):
|
||||
with redirect_stderr(StringIO()):
|
||||
with self.assertRaises(SystemExit):
|
||||
build_parser().parse_args(
|
||||
["verify", "--manifest", "shadow-manifest.json"]
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user