Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions eng/sdk/test-installed-macos-bundle-audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ def main():
if not installed.is_file():
relative = installed.relative_to(prefix)
raise RuntimeError(f"installed SDK surface is missing {relative}")
installed_before = {
path.relative_to(prefix).as_posix(): path.read_bytes()
for path in prefix.rglob("*") if path.is_file()
}

bundle = work / "Fixture.app"
macos = bundle / "Contents/MacOS"
Expand Down Expand Up @@ -101,6 +105,19 @@ def main():
"--maximum-audit-entries", "10000",
"--maximum-audit-evidence-bytes", str(64 * 1024),
], stdout=subprocess.DEVNULL)
installed_after = {
path.relative_to(prefix).as_posix(): path.read_bytes()
for path in prefix.rglob("*") if path.is_file()
}
if installed_after != installed_before:
added = sorted(set(installed_after) - set(installed_before))
changed = sorted(
path for path in set(installed_after) & set(installed_before)
if installed_after[path] != installed_before[path]
)
raise RuntimeError(
f"installed SDK mutated during packaging: added={added}, changed={changed}"
)
final_architectures = run(
["xcrun", "lipo", "-archs", str(extension)], capture_output=True
).stdout.split()
Expand Down
28 changes: 28 additions & 0 deletions eng/sdk/test-macos-bundle-audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import json
import os
from pathlib import Path
import shutil
import subprocess
import sys
import tempfile
import time
Expand Down Expand Up @@ -397,6 +399,32 @@ def test_packager_runs_audit_before_outer_signature(self):
"--maximum-audit-entries", "--maximum-audit-evidence-bytes"):
self.assertIn(option, source)

def test_packager_import_does_not_mutate_installed_tools(self):
with tempfile.TemporaryDirectory(prefix="webscene immutable tools ") as temporary:
tools = Path(temporary) / "share/webscene/tools"
tools.mkdir(parents=True)
for name in ("package_macos.py", "audit_macos_bundle.py"):
shutil.copy2(ROOT / "src/WebScene.Sdk/tools" / name, tools / name)
before = {
path.relative_to(tools).as_posix(): path.read_bytes()
for path in tools.rglob("*") if path.is_file()
}
started = time.monotonic()
for _ in range(100):
completed = subprocess.run(
[sys.executable, str(tools / "package_macos.py"), "--help"],
stdout=subprocess.DEVNULL, stderr=subprocess.PIPE,
text=True, timeout=10)
self.assertEqual(completed.returncode, 0, completed.stderr)
elapsed = time.monotonic() - started
after = {
path.relative_to(tools).as_posix(): path.read_bytes()
for path in tools.rglob("*") if path.is_file()
}
self.assertEqual(after, before)
self.assertFalse(any(path.name == "__pycache__" for path in tools.rglob("*")))
self.assertLess(elapsed, 15.0)

def test_single_architecture_normalization_is_atomic_and_idempotent(self):
extension_relative = "Contents/PlugIns/sample.node"
self.fixture.extension.write_bytes(b"\xca\xfe\xba\xbf" + bytes(range(128)))
Expand Down
5 changes: 5 additions & 0 deletions src/WebScene.Sdk/tools/package_macos.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
import platform
import shutil
import subprocess
import sys

# Installed SDK tools are immutable inputs. Prevent the adjacent module import
# below from materializing __pycache__ inside an otherwise verified SDK.
sys.dont_write_bytecode = True

from audit_macos_bundle import (
DEFAULT_MAXIMUM_ENTRIES,
Expand Down
Loading