Files
workinf_Blender_Wasm/my-tools/test_recover_behavior_contracts.py
mes123456 f3e21c6b98
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
chore: checkpoint web Blender migration source, tools and docs
Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer,
web workflow engine and protocol, tooling, docs and task records.
Large generated evidence, user-testing archives, build snapshots and
imported test assets remain untracked.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-11-10 11:18:01 +08:00

59 lines
2.7 KiB
Python

"""Synthetic recovery metadata tests, not Blender acceptance evidence."""
import hashlib
import json
import pathlib
import tempfile
import unittest
from recover_behavior_contracts import candidate, KINDS
class RecoveryTests(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.addCleanup(self.temp.cleanup)
self.root = pathlib.Path(self.temp.name)
self.worker = self.root / "run/worker-result.json"
self.worker.parent.mkdir()
self.contract = {"job": "SCULPT", "task": "TASK", "result": {"sourceUnits": ["stroke", "remesh"]}}
self.cases = [{"id": kind, "kind": kind, "unitIds": ["stroke", "remesh"],
"receipt": f"run/{kind}.json"} for kind in sorted(KINDS)]
self.worker.write_text(json.dumps({"cases": self.cases, "sourceUnits": ["stroke", "remesh"]}))
(self.root / "source.cc").write_text("synthetic source")
def digest(path):
return hashlib.sha256(path.read_bytes()).hexdigest()
artifacts = []
for case in self.cases:
path = self.root / case["receipt"]
path.write_text(json.dumps({"status": "PASS", "runtime": "CHROMIUM_WEBENGINE",
"caseId": case["id"], "kind": case["kind"], "unitIds": case["unitIds"]}))
artifacts.append({"path": case["receipt"], "sha256": digest(path)})
self.proof = self.root / "run/verified-receipt.json"
self.proof.write_text(json.dumps({"status": "verified", "job": "SCULPT", "queueTask": "TASK",
"sourceUnits": ["stroke", "remesh"], "artifacts": artifacts,
"inputs": {"source.cc": digest(self.root / "source.cc")}}))
def test_valid_metadata_is_rebound_for_fresh_execution(self):
result = candidate(self.worker, self.contract, self.root)
self.assertIsNotNone(result)
self.assertTrue(all(case["receipt"].startswith("unallocated/") for case in result["cases"]))
def test_case_count_without_verified_receipt_is_rejected(self):
self.proof.unlink()
self.assertIsNone(candidate(self.worker, self.contract, self.root))
def test_scope_cannot_drop_remesh(self):
self.worker.write_text(json.dumps({"cases": self.cases, "sourceUnits": ["stroke"]}))
self.assertIsNone(candidate(self.worker, self.contract, self.root))
def test_missing_receipt_is_rejected(self):
(self.root / self.cases[0]["receipt"]).unlink()
self.assertIsNone(candidate(self.worker, self.contract, self.root))
def test_changed_source_is_rejected(self):
(self.root / "source.cc").write_text("modified source")
self.assertIsNone(candidate(self.worker, self.contract, self.root))
if __name__ == "__main__":
unittest.main()