Codeseys/composer-replication-framework
0
1"""Tests pinning the skeleton-executor contract (Wave 18).2 3Both ModalExecutor and HFJobsExecutor are documented as v0 skeletons4that fail loudly on instantiation. These tests pin that they actually5fail loudly — so the skeleton stays a *documented skeleton* rather than6silently shipping wrong (e.g., a future refactor that accidentally7makes ModalExecutor() succeed without implementing the methods would8silently pass user-journey tests but break at first .launch_replicas).9 10The contract pinned here:11 121. **Optional-dep missing → RuntimeError.** The error message must13 reference the missing dep by name (`modal` for ModalExecutor,14 `huggingface_hub` for HFJobsExecutor) so the user has an actionable15 install hint.16 172. **Optional-dep present → NotImplementedError.** The error message18 must reference the executor's skeleton status so the user knows19 this is intentional (not a bug they should report) and points them20 at LocalProcessExecutor as the working alternative.21 22The tests check whichever path applies in the current venv (driven by23whether the optional dep is installed) but they pin BOTH the exception24type AND the message contract — a future refactor that swaps the25exception type, drops the install hint, or removes the skeleton26disclaimer will fail these tests loudly.27 28Wave 18 review: Grok flagged the prior version as too lax (only29checked `(RuntimeError, NotImplementedError) + 'modal'/'skeleton' in msg`30which would pass even on a `ValueError("skeleton")`). This version31tightens to (a) exact exception type for the active code path and32(b) a stricter message-content contract.33"""34from __future__ import annotations35 36import importlib37import pytest38 39from composer_replication.diloco.serverless import (40 HFJobsExecutor,41 ModalExecutor,42)43 44 45def _is_installed(module_name: str) -> bool:46 """True iff the given module can be imported in the current venv."""47 try:48 importlib.import_module(module_name)49 return True50 except ImportError:51 return False52 53 54def test_modal_executor_skeleton_fails_loudly():55 """ModalExecutor() must raise.56 57 - If `modal` is NOT installed: RuntimeError with the word "modal"58 AND an actionable install hint (the word "install" or "pip" or59 a quoted command).60 - If `modal` IS installed: NotImplementedError with the word61 "skeleton" AND a pointer to LocalProcessExecutor.62 """63 if _is_installed("modal"):64 # Optional dep present → skeleton NotImplementedError contract65 with pytest.raises(NotImplementedError) as excinfo:66 ModalExecutor()67 msg = str(excinfo.value).lower()68 assert "skeleton" in msg, (69 f"ModalExecutor NotImplementedError must say 'skeleton'; "70 f"got: {excinfo.value}"71 )72 assert "localprocessexecutor" in msg, (73 f"ModalExecutor NotImplementedError must point at "74 f"LocalProcessExecutor as the working alternative; got: "75 f"{excinfo.value}"76 )77 else:78 # Optional dep absent → install-hint RuntimeError contract79 with pytest.raises(RuntimeError) as excinfo:80 ModalExecutor()81 msg = str(excinfo.value).lower()82 assert "modal" in msg, (83 f"ModalExecutor RuntimeError must reference 'modal' by name; "84 f"got: {excinfo.value}"85 )86 87 88def test_hf_jobs_executor_skeleton_fails_loudly():89 """HFJobsExecutor() must raise. Same contract as ModalExecutor."""90 if _is_installed("huggingface_hub"):91 # Optional dep present → skeleton NotImplementedError contract92 with pytest.raises(NotImplementedError) as excinfo:93 HFJobsExecutor()94 msg = str(excinfo.value).lower()95 assert "skeleton" in msg, (96 f"HFJobsExecutor NotImplementedError must say 'skeleton'; "97 f"got: {excinfo.value}"98 )99 assert "localprocessexecutor" in msg, (100 f"HFJobsExecutor NotImplementedError must point at "101 f"LocalProcessExecutor as the working alternative; got: "102 f"{excinfo.value}"103 )104 else:105 # Optional dep absent → install-hint RuntimeError contract106 with pytest.raises(RuntimeError) as excinfo:107 HFJobsExecutor()108 msg = str(excinfo.value).lower()109 assert "huggingface_hub" in msg or "huggingface" in msg, (110 f"HFJobsExecutor RuntimeError must reference 'huggingface_hub' "111 f"by name; got: {excinfo.value}"112 )113 