"""用实际步骤轨迹回放定时选股;故意变异证明套件能识别假成功。""" import copy import json import unittest from datetime import datetime from decimal import Decimal as D, InvalidOperation SCHEDULER_ENABLED = False class Job: def __init__(self, mutation=None): self.seen, self.outputs, self.trace = set(), [], [] self.mutation = mutation def refresh(self, day, data): self.trace.append("refresh:"+day) return copy.deepcopy(data) def validate(self, day, data): self.trace.append("validate") if set(data) != {"AAA", "BBB"}: raise ValueError("missing_symbol") for row in data.values(): if row.get("date") != day or row.get("pe") is None: raise ValueError("missing_or_stale_field") try: pe = D(str(row["pe"])) except (InvalidOperation, ValueError, TypeError) as exc: raise ValueError("invalid_pe") from exc if not pe.is_finite() or pe <= 0: raise ValueError("invalid_pe") def screen(self, data): self.trace.append("screen") return sorted(s for s, row in data.items() if D(str(row["pe"])) < 20) def publish(self, slot, selected): self.trace.append("publish:"+slot) self.outputs.append({"slot": slot, "selected": selected}) self.seen.add(slot) def run(self, trigger, data): self.trace = [] now = datetime.fromisoformat(trigger) if now.utcoffset() is None or now.utcoffset().total_seconds() != 28800: raise ValueError("expected_fixed_plus08_timezone") day, slot = str(now.date()), "screen-v1:"+str(now.date()) if day not in {"2026-10-20", "2026-10-21"}: return "closed" if (now.hour, now.minute) < (16, 0): return "not_due" if slot in self.seen and self.mutation != "ignore_dedupe": return "duplicate" rows = copy.deepcopy(data) if self.mutation == "skip_refresh" else self.refresh(day, data) try: self.validate(day, rows) except ValueError: if self.mutation == "publish_before_validation": self.publish(slot, []) return "blocked" self.publish(slot, self.screen(rows)) return "success" def data(day): return {"AAA": {"date": day, "pe": "25"}, "BBB": {"date": day, "pe": "18"}} def run_suite(mutation=None): case = unittest.TestCase() job, evidence = Job(mutation), [] missing = data("2026-10-21") del missing["AAA"]["pe"] scenarios = [ ("premarket", "2026-10-20T08:00:00+08:00", data("2026-10-20"), "not_due", [], 0), ("normal", "2026-10-20T16:30:00+08:00", data("2026-10-20"), "success", ["refresh:2026-10-20", "validate", "screen", "publish:screen-v1:2026-10-20"], 1), ("duplicate", "2026-10-20T17:00:00+08:00", data("2026-10-20"), "duplicate", [], 1), ("closed", "2026-10-24T16:30:00+08:00", data("2026-10-24"), "closed", [], 1), ("missing", "2026-10-21T16:30:00+08:00", missing, "blocked", ["refresh:2026-10-21", "validate"], 1), ("repaired", "2026-10-21T16:45:00+08:00", data("2026-10-21"), "success", ["refresh:2026-10-21", "validate", "screen", "publish:screen-v1:2026-10-21"], 2), ] for name, trigger, payload, expected, trace, count in scenarios: actual = job.run(trigger, payload) case.assertEqual(actual, expected, name+":status") case.assertEqual(job.trace, trace, name+":trace") case.assertEqual(len(job.outputs), count, name+":output_count") evidence.append({"case": name, "status": actual, "trace": list(job.trace), "output_count": count}) case.assertEqual([r["slot"] for r in job.outputs], ["screen-v1:2026-10-20", "screen-v1:2026-10-21"]) case.assertTrue(all(r["selected"] == ["BBB"] for r in job.outputs)) return evidence baseline = run_suite() killed = [] for mutation in ["ignore_dedupe", "skip_refresh", "publish_before_validation"]: try: run_suite(mutation) except AssertionError as exc: killed.append({"mutation": mutation, "detected": str(exc).splitlines()[-1]}) else: raise AssertionError("测试必须识别注入错误:"+mutation) replay = run_suite() assert replay == baseline and len(killed) == 3 and SCHEDULER_ENABLED is False for token in ["NaN", "Infinity", "-Infinity"]: job = Job() invalid = data("2026-10-20") invalid["AAA"]["pe"] = token assert job.run("2026-10-20T16:30:00+08:00", invalid) == "blocked" and not job.outputs print(json.dumps({"scenarios": baseline, "mutations_detected": killed, "replay_cases": len(replay), "scheduler_enabled": SCHEDULER_ENABLED}, sort_keys=True))