77 lines
3.5 KiB
Python
77 lines
3.5 KiB
Python
import importlib.util
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
|
|
MODULE_PATH = Path(__file__).parents[2] / "autoinstall/offline/plan-python-runtime-profile.py"
|
|
SPEC = importlib.util.spec_from_file_location("plan_python_runtime_profile", MODULE_PATH)
|
|
MODULE = importlib.util.module_from_spec(SPEC)
|
|
assert SPEC.loader
|
|
SPEC.loader.exec_module(MODULE)
|
|
|
|
|
|
RECEIPT = {
|
|
"schema": "com.cezen.nexus-one.profile-membership-verification-receipt.v1",
|
|
"environment": "production",
|
|
"result": "verified",
|
|
"manifest_sha256": "a" * 64,
|
|
"namespace": "offline-workstation/python-runtime-profiles",
|
|
"profiles": ["cpu-only", "nvidia-cu128"],
|
|
}
|
|
|
|
|
|
class PythonRuntimeProfilePlanTests(unittest.TestCase):
|
|
def test_auto_defaults_to_cpu_when_nvidia_probe_is_incomplete(self):
|
|
result = MODULE.plan({"architecture": "amd64", "nvidia": {"present": True}}, RECEIPT,
|
|
"auto", "op-1", None)
|
|
self.assertEqual(result["selected_profile"], "cpu-only")
|
|
|
|
def test_auto_selects_nvidia_only_when_all_readiness_facts_pass(self):
|
|
probe = {"architecture": "amd64", "nvidia": {
|
|
"present": True, "supported": True, "driver_ready": True,
|
|
}}
|
|
result = MODULE.plan(probe, RECEIPT, "auto", "op-1", None)
|
|
self.assertEqual(result["selected_profile"], "nvidia-cu128")
|
|
|
|
def test_unverified_or_unsigned_profile_fails_closed(self):
|
|
with self.assertRaises(MODULE.PlanError) as invalid:
|
|
MODULE.plan({"architecture": "amd64"}, {}, "auto", "op-1", None)
|
|
self.assertEqual(invalid.exception.code, "MEMBERSHIP_RECEIPT_INVALID")
|
|
receipt = {**RECEIPT, "profiles": ["cpu-only"]}
|
|
probe = {"architecture": "amd64", "nvidia": {
|
|
"present": True, "supported": True, "driver_ready": True,
|
|
}}
|
|
with self.assertRaisesRegex(MODULE.PlanError, "not signed membership"):
|
|
MODULE.plan(probe, receipt, "auto", "op-1", None)
|
|
|
|
def test_test_receipt_requires_explicit_test_mode(self):
|
|
receipt = {**RECEIPT, "environment": "test"}
|
|
with self.assertRaises(MODULE.PlanError) as forbidden:
|
|
MODULE.plan({"architecture": "amd64"}, receipt, "auto", "op-1", None)
|
|
self.assertEqual(forbidden.exception.code, "TEST_RECEIPT_FORBIDDEN")
|
|
result = MODULE.plan({"architecture": "amd64"}, receipt, "auto", "op-1", None, True)
|
|
self.assertEqual(result["selected_profile"], "cpu-only")
|
|
|
|
def test_resume_reuses_recorded_profile(self):
|
|
journal = {"operation_id": "op-1", "selected_profile": "cpu-only", "state": "installing"}
|
|
result = MODULE.plan({"architecture": "amd64"}, RECEIPT, "cpu-only", "op-1", journal)
|
|
self.assertEqual(result["action"], "resume")
|
|
|
|
def test_profile_change_requires_rollback(self):
|
|
journal = {"operation_id": "op-1", "selected_profile": "cpu-only", "state": "installing"}
|
|
probe = {"architecture": "amd64", "nvidia": {
|
|
"present": True, "supported": True, "driver_ready": True,
|
|
}}
|
|
with self.assertRaises(MODULE.PlanError) as raised:
|
|
MODULE.plan(probe, RECEIPT, "nvidia-cu128", "op-1", journal)
|
|
self.assertEqual(raised.exception.code, "PROFILE_CHANGE_REQUIRES_ROLLBACK")
|
|
|
|
def test_rolled_back_operation_id_cannot_be_reused(self):
|
|
journal = {"operation_id": "op-1", "selected_profile": "cpu-only", "state": "rolled_back"}
|
|
with self.assertRaisesRegex(MODULE.PlanError, "new operation id"):
|
|
MODULE.plan({"architecture": "amd64"}, RECEIPT, "cpu-only", "op-1", journal)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|