"""Static UID policy cases; no engine, native worker or regression invocation.""" import importlib.util from pathlib import Path import sys import tempfile import unittest sys.dont_write_bytecode = True TOOLS = Path(__file__).resolve().parents[2] / 'tools' sys.path.insert(0, str(TOOLS)) spec = importlib.util.spec_from_file_location('p13_uid_policy', TOOLS / 'run_p13_reference_tests.py') runner = importlib.util.module_from_spec(spec) spec.loader.exec_module(runner) class UIDPolicyTests(unittest.TestCase): def setUp(self): self.tmp = tempfile.TemporaryDirectory() self.addCleanup(self.tmp.cleanup) self.stage = Path(self.tmp.name) self.owner = 'tests/special/example.gd' self.other = 'scripts/special/peeping_room_service.gd' for name in (self.owner, self.other): self.write(name, b'extends RefCounted\n') self.write('project.godot', b'[application]\n') self.write('scripts/existing.gd.uid', b'uid://existing\n') self.source = runner.shared.inventory(self.stage, stage=True) self.plan = runner.uid_plan(self.source) self.write(self.owner + '.uid', b'uid://first\n') self.write(self.other + '.uid', b'uid://second\n') def write(self, name, raw): path = self.stage / name path.parent.mkdir(parents=True, exist_ok=True) path.write_bytes(raw) def snapshot(self): return runner.uid_snapshot(self.stage, self.source, self.plan) def test_accept_and_owner_seal(self): accepted = self.snapshot() self.assertEqual(set(accepted), {self.owner + '.uid', self.other + '.uid'}) pin = accepted[self.owner + '.uid'] self.assertEqual(pin['raw_bytes'], list(b'uid://first\n')) self.assertEqual(pin['text'], 'uid://first\n') self.assertEqual(pin['owner_sha256'], self.source[self.owner]['sha256']) self.assertEqual(pin['sha256'], runner.shared.sha(self.stage / (self.owner + '.uid'))) def test_unknown_and_extra(self): for name in ('scripts/unknown.gd.uid', 'extra.txt'): with self.subTest(name=name): self.write(name, b'uid://extra\n') with self.assertRaises(AssertionError): self.snapshot() (self.stage / name).unlink() def test_missing(self): (self.stage / (self.owner + '.uid')).unlink() with self.assertRaises(AssertionError): self.snapshot() def test_malformed(self): for raw in (b'uid://UPPER\n', b'uid://first', b'uid://first\nextra', b'uid://12345678901234\n', b'uid://\n', b'uid://first\r\n'): with self.subTest(raw=raw): self.write(self.owner + '.uid', raw) with self.assertRaises(AssertionError): self.snapshot() def test_duplicate_and_existing_collision(self): for raw in (b'uid://second\n', b'uid://existing\n'): with self.subTest(raw=raw): self.write(self.owner + '.uid', raw) with self.assertRaises(AssertionError): self.snapshot() def test_modified_original(self): for name in (self.owner, 'project.godot', 'scripts/existing.gd.uid'): with self.subTest(name=name): path = self.stage / name original = path.read_bytes() path.write_bytes(original + b'tamper') with self.assertRaises(AssertionError): self.snapshot() path.write_bytes(original) def test_symlink(self): path = self.stage / (self.owner + '.uid') path.unlink() path.symlink_to(self.stage / (self.other + '.uid')) with self.assertRaises(AssertionError): self.snapshot() if __name__ == '__main__': unittest.main()