83 lines
3.4 KiB
Python
83 lines
3.4 KiB
Python
import os
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
from scripts.macos_dmg import MIB, image_size_mib
|
|
|
|
|
|
class DmgSizingTests(unittest.TestCase):
|
|
def test_sparse_binary_uses_logical_size(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
root = Path(temporary)
|
|
with (root / "pebrel").open("wb") as stream:
|
|
stream.truncate(512 * MIB)
|
|
self.assertGreater(image_size_mib(root), 640)
|
|
|
|
@unittest.skipIf(os.name == "nt", "requires unprivileged symlinks")
|
|
def test_application_link_does_not_follow_external_files(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
root = Path(temporary)
|
|
stage = root / "stage"
|
|
stage.mkdir()
|
|
external = root / "Applications"
|
|
external.mkdir()
|
|
with (external / "large").open("wb") as stream:
|
|
stream.truncate(1024 * MIB)
|
|
(stage / "Applications").symlink_to(external, target_is_directory=True)
|
|
self.assertEqual(image_size_mib(stage), 64)
|
|
|
|
def test_small_files_include_allocation_overhead(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
root = Path(temporary)
|
|
for index in range(100):
|
|
(root / str(index)).write_bytes(b"x")
|
|
self.assertGreaterEqual(image_size_mib(root), 64)
|
|
|
|
def test_missing_source_is_rejected(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
with self.assertRaises(ValueError):
|
|
image_size_mib(Path(temporary) / "missing")
|
|
|
|
@unittest.skipUnless(sys.platform == "darwin", "requires native hdiutil")
|
|
def test_native_image_contains_complete_sparse_binary(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
root = Path(temporary)
|
|
stage = root / "stage"
|
|
executable = stage / "Pebrel Preview.app/Contents/MacOS/pebrel"
|
|
executable.parent.mkdir(parents=True)
|
|
with executable.open("wb") as stream:
|
|
stream.write(b"pebrel-start")
|
|
stream.seek(64 * MIB)
|
|
stream.write(b"pebrel-end")
|
|
(stage / "Applications").symlink_to("/Applications")
|
|
image = root / "test.dmg"
|
|
subprocess.run([
|
|
"hdiutil", "create", "-volname", "Pebrel Preview", "-fs", "HFS+",
|
|
"-size", f"{image_size_mib(stage)}m", "-srcfolder", str(stage),
|
|
"-format", "UDZO", str(image),
|
|
], check=True, capture_output=True)
|
|
mount = root / "mount"
|
|
mount.mkdir()
|
|
subprocess.run([
|
|
"hdiutil", "attach", str(image), "-nobrowse", "-readonly",
|
|
"-mountpoint", str(mount),
|
|
], check=True, capture_output=True)
|
|
try:
|
|
copied = mount / executable.relative_to(stage)
|
|
self.assertEqual(copied.stat().st_size, executable.stat().st_size)
|
|
with copied.open("rb") as stream:
|
|
self.assertEqual(stream.read(12), b"pebrel-start")
|
|
stream.seek(64 * MIB)
|
|
self.assertEqual(stream.read(), b"pebrel-end")
|
|
self.assertEqual(os.readlink(mount / "Applications"), "/Applications")
|
|
finally:
|
|
subprocess.run(["hdiutil", "detach", str(mount)], check=True,
|
|
capture_output=True)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|