mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 00:22:57 -05:00
110 lines
5.4 KiB
Python
110 lines
5.4 KiB
Python
import contextlib
|
|
import hashlib
|
|
import io
|
|
import json
|
|
from pathlib import Path
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from unittest.mock import patch
|
|
import warnings
|
|
import zipfile
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
import build_web
|
|
|
|
|
|
def library_zip(entries):
|
|
buffer = io.BytesIO()
|
|
with warnings.catch_warnings(), zipfile.ZipFile(buffer, "w", compression=zipfile.ZIP_DEFLATED) as archive:
|
|
warnings.simplefilter("ignore", UserWarning)
|
|
for name, data in entries:
|
|
archive.writestr(name, data)
|
|
return buffer.getvalue()
|
|
|
|
|
|
class LibraryPublicationTests(unittest.TestCase):
|
|
def test_expanded_limit_is_checked_before_decompression(self):
|
|
payload = library_zip([("libs/libc.prx", b"a" * 4097)])
|
|
with patch.object(build_web, "MAX_EXPANDED_BYTES", 4096, create=True), \
|
|
patch.object(zipfile.ZipFile, "testzip", side_effect=AssertionError("archive decompressed")):
|
|
with self.assertRaisesRegex(ValueError, "expanded size"):
|
|
self.publish(payload, payload)
|
|
self.assertEqual(self.manifest.read_bytes(), self.previous)
|
|
self.assertEqual(list(self.libraries.iterdir()), [self.existing])
|
|
|
|
|
|
def test_expanded_limit_boundary_can_be_published(self):
|
|
payload = library_zip([("libs/libc.prx", b"a" * 4096)])
|
|
with patch.object(build_web, "MAX_EXPANDED_BYTES", 4096, create=True):
|
|
self.publish(payload, payload)
|
|
report = json.loads(self.manifest.read_text(encoding="utf-8"))
|
|
self.assertTrue(all(asset["expandedBytes"] == 4096 for asset in report["platforms"].values()))
|
|
|
|
|
|
def setUp(self):
|
|
temporary = tempfile.TemporaryDirectory()
|
|
self.addCleanup(temporary.cleanup)
|
|
self.output = Path(temporary.name)
|
|
self.libraries = self.output / "libraries"
|
|
self.libraries.mkdir()
|
|
self.manifest = self.output / "release.json"
|
|
self.previous = b'{"tag":"previous complete release"}\n'
|
|
self.manifest.write_bytes(self.previous)
|
|
self.existing = self.libraries / "previous.zip"
|
|
self.existing.write_bytes(b"previous archive")
|
|
|
|
def publish(self, windows, linux):
|
|
assets = []
|
|
responses = {}
|
|
for platform, data in (("windows", windows), ("linux", linux)):
|
|
url = f"https://example.invalid/{platform}.zip"
|
|
assets.append({"name": f"prx-{platform}-v1.zip", "size": len(data),
|
|
"digest": "sha256:" + hashlib.sha256(data).hexdigest(), "browser_download_url": url})
|
|
responses[url] = data
|
|
release = {"tag_name": "v1", "html_url": "https://example.invalid/v1", "assets": assets}
|
|
responses["https://api.github.com/repos/boykopovar/AnyPS5/releases/latest"] = json.dumps(release).encode()
|
|
with patch.object(build_web, "request", side_effect=lambda url: io.BytesIO(responses[url])), \
|
|
contextlib.redirect_stdout(io.StringIO()):
|
|
build_web.publish_libraries(self.output)
|
|
|
|
def test_colliding_paths_do_not_publish_a_release(self):
|
|
valid = library_zip([("libs/libc.prx", b"valid archive")])
|
|
for first, second in (("libs/libc.prx", "libs/libc.prx"),
|
|
("libs/libc.prx", "libs/LIBC.prx"),
|
|
("libs/extra/", "libs/EXTRA")):
|
|
with self.subTest(first=first, second=second):
|
|
invalid = library_zip([(first, b"" if first.endswith("/") else b"first"), (second, b"second")])
|
|
with self.assertRaisesRegex(ValueError, "Duplicate library archive path"):
|
|
self.publish(invalid, valid)
|
|
self.assertEqual(self.manifest.read_bytes(), self.previous)
|
|
self.assertEqual(self.existing.read_bytes(), b"previous archive")
|
|
self.assertEqual(list(self.libraries.iterdir()), [self.existing])
|
|
|
|
def test_collision_in_second_platform_preserves_previous_manifest(self):
|
|
valid = library_zip([("libs/libc.prx", b"valid archive")])
|
|
invalid = library_zip([("libs/libc.prx", b"first"), ("libs/LIBC.prx", b"second")])
|
|
with self.assertRaisesRegex(ValueError, "Duplicate library archive path"):
|
|
self.publish(valid, invalid)
|
|
self.assertEqual(self.manifest.read_bytes(), self.previous)
|
|
self.assertEqual(self.existing.read_bytes(), b"previous archive")
|
|
self.assertFalse(any(file.suffix == ".download" for file in self.libraries.iterdir()))
|
|
|
|
def test_distinct_full_paths_publish_both_platforms(self):
|
|
payload = library_zip([("libs/", b""), ("libs/libc.prx", b"first"), ("libs/extra/libc.prx", b"second")])
|
|
self.publish(payload, payload)
|
|
manifest = json.loads(self.manifest.read_text(encoding="utf-8"))
|
|
self.assertEqual(manifest["tag"], "v1")
|
|
self.assertEqual(set(manifest["platforms"]), {"windows", "linux"})
|
|
for platform, asset in manifest["platforms"].items():
|
|
digest = hashlib.sha256(payload).hexdigest()
|
|
self.assertEqual(asset, {"path": f"libraries/{platform}-{digest}.zip", "size": len(payload),
|
|
"expandedBytes": 11, "sha256": digest})
|
|
self.assertEqual((self.output / asset["path"]).read_bytes(), payload)
|
|
self.assertEqual(self.existing.read_bytes(), b"previous archive")
|
|
self.assertFalse(any(file.suffix == ".download" for file in self.libraries.iterdir()))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|