97 lines
3.8 KiB
Python
97 lines
3.8 KiB
Python
"""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()
|