Files
Magent/backend/tests/test_container_packaging.py
T

123 lines
6.0 KiB
Python

"""Unit checks for the release smoke harness; no Docker or network required."""
from email.message import Message
from email.parser import BytesParser
from email.policy import default
import importlib.util
from pathlib import Path
import unittest
from unittest.mock import patch
HELPER_PATH = Path(__file__).resolve().parents[2] / "scripts" / "container_smoke.py"
SPEC = importlib.util.spec_from_file_location("magent_container_smoke", HELPER_PATH)
smoke = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(smoke)
def response_headers(**changes):
headers = Message()
for key, value in {
"Content-Type": "text/html; charset=utf-8",
"Content-Security-Policy": "default-src 'self'; script-src 'self' 'nonce-test-nonce' 'strict-dynamic'",
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
**changes,
}.items():
headers[key] = value
return headers
class ContainerPackagingHarnessTests(unittest.TestCase):
def test_backup_multipart_preserves_binary_content_and_required_fields(self):
content = b"MAGENT-BACKUP\x00\x01\xff\r\n\x00encrypted"
body, content_type = smoke.backup_restore_upload(content, "synthetic backup passphrase")
parsed = BytesParser(policy=default).parsebytes(
f"Content-Type: {content_type}\r\nMIME-Version: 1.0\r\n\r\n".encode() + body,
)
fields = {part.get_param("name", header="content-disposition"): part
for part in parsed.iter_parts()}
self.assertEqual(set(fields), {"passphrase", "confirmation", "file"})
self.assertEqual(fields["passphrase"].get_payload(decode=True), b"synthetic backup passphrase")
self.assertEqual(fields["confirmation"].get_payload(decode=True), b"RESTORE")
self.assertEqual(fields["file"].get_payload(decode=True), content)
self.assertEqual(fields["file"].get_filename(), "smoke.magent-backup")
def test_http_rejects_conflicting_body_encodings_without_network(self):
with patch.object(smoke.request, "urlopen") as urlopen:
with self.assertRaisesRegex(AssertionError, "only one encoding"):
smoke.http("/test", payload={}, raw=b"binary")
urlopen.assert_not_called()
def page(self, *, nonce="test-nonce", source="/_next/static/app.js", extra=""):
return (
f'<script nonce="{nonce}" src="{source}"></script>'
f'<script nonce="{nonce}">self.__next_f.push([])</script>'
'<link rel="stylesheet" href="/_next/static/app.css">'
f"{extra}"
).encode()
def test_static_assets_and_every_bootstrap_script_are_validated(self):
seen = []
def fake_http(path):
seen.append(path)
if path == "/login":
return self.page(), response_headers()
return b"static content", response_headers(**{"Content-Type": "application/javascript"})
with patch.object(smoke, "http", side_effect=fake_http):
assets = set()
self.assertEqual(smoke.check_page("/login", assets), "test-nonce")
self.assertEqual(assets, {"/_next/static/app.js", "/_next/static/app.css"})
self.assertEqual(seen, ["/login", "/_next/static/app.css", "/_next/static/app.js"])
smoke.check_page("/login", assets)
self.assertEqual(seen[-1], "/login")
self.assertEqual(len(seen), 4)
def test_nonce_mismatch_fails_before_fetching_assets(self):
with patch.object(smoke, "http", return_value=(self.page(nonce="wrong"), response_headers())):
with self.assertRaisesRegex(AssertionError, "script blocked by its CSP nonce"):
smoke.check_page("/login", set())
def test_missing_nonce_policy_is_rejected(self):
headers = response_headers(**{"Content-Security-Policy": "script-src 'self'"})
with patch.object(smoke, "http", return_value=(self.page(), headers)):
with self.assertRaisesRegex(AssertionError, "missing script nonce policy"):
smoke.check_page("/login", set())
def test_development_eval_policy_is_rejected(self):
headers = response_headers(**{
"Content-Security-Policy": "script-src 'nonce-test-nonce' 'strict-dynamic' 'unsafe-eval'",
})
with patch.object(smoke, "http", return_value=(self.page(), headers)):
with self.assertRaisesRegex(AssertionError, "development eval"):
smoke.check_page("/login", set())
def test_html_fallback_for_static_asset_is_rejected(self):
with patch.object(smoke, "http", return_value=(self.page(), response_headers())):
with self.assertRaisesRegex(AssertionError, "Asset returned HTML"):
smoke.check_page("/login", set())
def test_missing_executable_script_nonce_is_rejected(self):
page = self.page(extra='<script src="/_next/static/missing-nonce.js"></script>')
with patch.object(smoke, "http", return_value=(page, response_headers())):
with self.assertRaisesRegex(AssertionError, "script blocked by its CSP nonce"):
smoke.check_page("/login", set())
def test_inert_json_scripts_do_not_require_executable_nonce(self):
page = self.page(extra='<script type="application/ld+json">{"name":"Magent"}</script>')
with patch.object(smoke, "http", return_value=(page, response_headers())):
cache = {"/_next/static/app.js", "/_next/static/app.css"}
self.assertEqual(smoke.check_page("/login", cache), "test-nonce")
def test_external_scripts_are_not_followed_by_smoke_harness(self):
page = self.page(extra='<script nonce="test-nonce" src="https://external.invalid/app.js"></script>')
with patch.object(smoke, "http", return_value=(page, response_headers())):
with self.assertRaisesRegex(AssertionError, "Unexpected external executable asset"):
smoke.check_page("/login", {"/_next/static/app.js", "/_next/static/app.css"})
if __name__ == "__main__":
unittest.main()