Enable more slow integration tests
Authored by
mfwolffe <wolffemf@dukes.jmu.edu>
- SHA
20cfe6f88862ac844cae71b785f168831e8a643d- Parents
-
510e78c - Tree
eb852e9
20cfe6f
20cfe6f88862ac844cae71b785f168831e8a643d510e78c
eb852e9tests/integration/train/multi_adapter/test_prompt_and_export_named.pymodified@@ -57,17 +57,12 @@ def _skip_if_tiny_model_unavailable() -> None: | ||
| 57 | 57 | |
| 58 | 58 | def _train_two(tmp_path_factory: pytest.TempPathFactory) -> Path: |
| 59 | 59 | """Train knowledge + tone on a prose doc; return the .dlm path.""" |
| 60 | - from dlm.base_models import resolve as resolve_base_model | |
| 61 | 60 | from dlm.doc.parser import parse_file |
| 62 | - from dlm.hardware import doctor | |
| 63 | 61 | from dlm.store.manifest import Manifest, save_manifest |
| 64 | 62 | from dlm.store.paths import for_dlm |
| 65 | 63 | from dlm.train.multi_adapter.trainer import run_all |
| 66 | 64 | from tests.fixtures.dlm_factory import make_dlm, prose |
| 67 | - | |
| 68 | - plan = doctor().plan | |
| 69 | - if plan is None: | |
| 70 | - pytest.skip("doctor() returned no viable training plan on this host") | |
| 65 | + from tests.fixtures.planning import resolve_spec_and_plan | |
| 71 | 66 | |
| 72 | 67 | for key in ("HF_HUB_OFFLINE", "TRANSFORMERS_OFFLINE", "HF_DATASETS_OFFLINE"): |
| 73 | 68 | os.environ.pop(key, None) |
@@ -96,7 +91,7 @@ def _train_two(tmp_path_factory: pytest.TempPathFactory) -> Path: | ||
| 96 | 91 | doc.write_text(raw[:fm_end] + "\n" + _PROSE, encoding="utf-8") |
| 97 | 92 | |
| 98 | 93 | parsed = parse_file(doc) |
| 99 | - spec = resolve_base_model(parsed.frontmatter.base_model, accept_license=True) | |
| 94 | + spec, plan, _caps = resolve_spec_and_plan(parsed, accept_license=True) | |
| 100 | 95 | store = for_dlm(parsed.frontmatter.dlm_id) |
| 101 | 96 | store.ensure_layout() |
| 102 | 97 | save_manifest( |
@@ -134,11 +129,10 @@ def test_load_for_inference_resolves_each_named_adapter( | ||
| 134 | 129 | _skip_if_deps_missing() |
| 135 | 130 | _skip_if_tiny_model_unavailable() |
| 136 | 131 | |
| 137 | - from dlm.base_models import resolve as resolve_base_model | |
| 138 | 132 | from dlm.doc.parser import parse_file |
| 139 | - from dlm.hardware import doctor | |
| 140 | 133 | from dlm.inference.loader import load_for_inference, resolve_adapter_path |
| 141 | 134 | from dlm.store.paths import for_dlm |
| 135 | + from tests.fixtures.planning import resolve_spec_and_plan | |
| 142 | 136 | |
| 143 | 137 | doc = _train_two(tmp_path_factory) |
| 144 | 138 | parsed = parse_file(doc) |
@@ -151,8 +145,7 @@ def test_load_for_inference_resolves_each_named_adapter( | ||
| 151 | 145 | assert k_path.is_dir() |
| 152 | 146 | assert t_path.is_dir() |
| 153 | 147 | |
| 154 | - spec = resolve_base_model(parsed.frontmatter.base_model, accept_license=True) | |
| 155 | - caps = doctor().capabilities | |
| 148 | + spec, _plan, caps = resolve_spec_and_plan(parsed, accept_license=True) | |
| 156 | 149 | |
| 157 | 150 | # Full load exercises the PEFT adapter-load path on both names. |
| 158 | 151 | loaded_k = load_for_inference(store, spec, caps, adapter_name="knowledge") |
@@ -171,9 +164,9 @@ def test_export_named_adapter_records_adapter_name( | ||
| 171 | 164 | _skip_if_tiny_model_unavailable() |
| 172 | 165 | |
| 173 | 166 | try: |
| 174 | - from dlm.export.vendoring import resolve_llama_cpp_paths | |
| 167 | + from dlm.export.vendoring import llama_quantize_bin | |
| 175 | 168 | |
| 176 | - resolve_llama_cpp_paths() # probes the submodule; raises if missing | |
| 169 | + llama_quantize_bin() # probes the vendored quantize binary; raises if missing | |
| 177 | 170 | except Exception as exc: |
| 178 | 171 | pytest.skip(f"llama.cpp vendoring unavailable: {exc}") |
| 179 | 172 | |
tests/integration/train/multi_adapter/test_two_adapters.pymodified@@ -60,17 +60,12 @@ def test_two_adapters_each_get_their_own_version_history( | ||
| 60 | 60 | except Exception as exc: |
| 61 | 61 | pytest.skip(f"tiny-model fixture unavailable: {exc}") |
| 62 | 62 | |
| 63 | - from dlm.base_models import resolve as resolve_base_model | |
| 64 | 63 | from dlm.doc.parser import parse_file |
| 65 | - from dlm.hardware import doctor | |
| 66 | 64 | from dlm.store.manifest import Manifest, load_manifest, save_manifest |
| 67 | 65 | from dlm.store.paths import for_dlm |
| 68 | 66 | from dlm.train.multi_adapter.trainer import run_all |
| 69 | 67 | from tests.fixtures.dlm_factory import make_dlm, prose |
| 70 | - | |
| 71 | - plan = doctor().plan | |
| 72 | - if plan is None: | |
| 73 | - pytest.skip("doctor() returned no viable training plan on this host") | |
| 68 | + from tests.fixtures.planning import resolve_spec_and_plan | |
| 74 | 69 | |
| 75 | 70 | # Unset offline env so weights can download on cold caches. |
| 76 | 71 | for key in ("HF_HUB_OFFLINE", "TRANSFORMERS_OFFLINE", "HF_DATASETS_OFFLINE"): |
@@ -108,7 +103,7 @@ def test_two_adapters_each_get_their_own_version_history( | ||
| 108 | 103 | assert parsed.frontmatter.training.adapters is not None |
| 109 | 104 | assert set(parsed.frontmatter.training.adapters) == {"knowledge", "tone"} |
| 110 | 105 | |
| 111 | - spec = resolve_base_model(parsed.frontmatter.base_model, accept_license=True) | |
| 106 | + spec, plan, _caps = resolve_spec_and_plan(parsed, accept_license=True) | |
| 112 | 107 | store = for_dlm(parsed.frontmatter.dlm_id) |
| 113 | 108 | store.ensure_layout() |
| 114 | 109 | save_manifest( |
tests/integration/train/multi_adapter/test_weighted_merge.pymodified@@ -56,17 +56,12 @@ def _train_two_adapters( | ||
| 56 | 56 | except Exception as exc: |
| 57 | 57 | pytest.skip(f"tiny-model fixture unavailable: {exc}") |
| 58 | 58 | |
| 59 | - from dlm.base_models import resolve as resolve_base_model | |
| 60 | 59 | from dlm.doc.parser import parse_file |
| 61 | - from dlm.hardware import doctor | |
| 62 | 60 | from dlm.store.manifest import Manifest, save_manifest |
| 63 | 61 | from dlm.store.paths import for_dlm |
| 64 | 62 | from dlm.train.multi_adapter.trainer import run_all |
| 65 | 63 | from tests.fixtures.dlm_factory import make_dlm, prose |
| 66 | - | |
| 67 | - plan = doctor().plan | |
| 68 | - if plan is None: | |
| 69 | - pytest.skip("doctor() returned no viable training plan on this host") | |
| 64 | + from tests.fixtures.planning import resolve_spec_and_plan | |
| 70 | 65 | |
| 71 | 66 | for key in ("HF_HUB_OFFLINE", "TRANSFORMERS_OFFLINE", "HF_DATASETS_OFFLINE"): |
| 72 | 67 | os.environ.pop(key, None) |
@@ -88,7 +83,7 @@ def _train_two_adapters( | ||
| 88 | 83 | doc.write_text(raw[:fm_end] + "\n" + _PROSE, encoding="utf-8") |
| 89 | 84 | |
| 90 | 85 | parsed = parse_file(doc) |
| 91 | - spec = resolve_base_model(parsed.frontmatter.base_model, accept_license=True) | |
| 86 | + spec, plan, _caps = resolve_spec_and_plan(parsed, accept_license=True) | |
| 92 | 87 | store = for_dlm(parsed.frontmatter.dlm_id) |
| 93 | 88 | store.ensure_layout() |
| 94 | 89 | save_manifest( |
tests/integration/train/preference/test_dpo_tinymodel.pymodified@@ -24,11 +24,10 @@ pytestmark = pytest.mark.slow | ||
| 24 | 24 | |
| 25 | 25 | @pytest.mark.slow |
| 26 | 26 | def test_dpo_phase_writes_second_adapter_version(trained_store) -> None: # type: ignore[no-untyped-def] |
| 27 | - from dlm.base_models import resolve as resolve_base_model | |
| 28 | 27 | from dlm.doc.parser import parse_file |
| 29 | - from dlm.hardware import doctor | |
| 30 | 28 | from dlm.store.manifest import load_manifest |
| 31 | 29 | from dlm.train.preference.phase_orchestrator import run_phases |
| 30 | + from tests.fixtures.planning import resolve_spec_and_plan | |
| 32 | 31 | |
| 33 | 32 | store = trained_store.store |
| 34 | 33 | dlm_path = trained_store.doc |
@@ -37,10 +36,11 @@ def test_dpo_phase_writes_second_adapter_version(trained_store) -> None: # type | ||
| 37 | 36 | _append_preference_section(dlm_path, terse_preferences) |
| 38 | 37 | |
| 39 | 38 | parsed = parse_file(dlm_path) |
| 40 | - spec = resolve_base_model(parsed.frontmatter.base_model, accept_license=True) | |
| 41 | - plan = doctor().plan | |
| 42 | - if plan is None: | |
| 43 | - pytest.skip("no viable plan on this host — DPO body needs a real trainer") | |
| 39 | + spec, plan, capabilities = resolve_spec_and_plan( | |
| 40 | + parsed, | |
| 41 | + accept_license=True, | |
| 42 | + skip_reason="no viable plan on this host — DPO body needs a real trainer", | |
| 43 | + ) | |
| 44 | 44 | |
| 45 | 45 | prior_manifest = load_manifest(store.manifest) |
| 46 | 46 | assert prior_manifest.adapter_version == 1 |
@@ -51,7 +51,7 @@ def test_dpo_phase_writes_second_adapter_version(trained_store) -> None: # type | ||
| 51 | 51 | spec, |
| 52 | 52 | plan, |
| 53 | 53 | phase="preference", |
| 54 | - capabilities=doctor().capabilities, | |
| 54 | + capabilities=capabilities, | |
| 55 | 55 | ) |
| 56 | 56 | assert [r.phase for r in results] == ["preference"] |
| 57 | 57 | dpo_result = results[0].result |
tests/integration/train/preference/test_orpo_tinymodel.pymodified@@ -17,12 +17,11 @@ pytestmark = pytest.mark.slow | ||
| 17 | 17 | |
| 18 | 18 | @pytest.mark.slow |
| 19 | 19 | def test_orpo_phase_writes_second_adapter_version(trained_store) -> None: # type: ignore[no-untyped-def] |
| 20 | - from dlm.base_models import resolve as resolve_base_model | |
| 21 | 20 | from dlm.doc.parser import parse_file |
| 22 | 21 | from dlm.doc.serializer import serialize |
| 23 | - from dlm.hardware import doctor | |
| 24 | 22 | from dlm.store.manifest import load_manifest |
| 25 | 23 | from dlm.train.preference.phase_orchestrator import run_phases |
| 24 | + from tests.fixtures.planning import resolve_spec_and_plan | |
| 26 | 25 | |
| 27 | 26 | store = trained_store.store |
| 28 | 27 | dlm_path = trained_store.doc |
@@ -45,10 +44,11 @@ def test_orpo_phase_writes_second_adapter_version(trained_store) -> None: # typ | ||
| 45 | 44 | parsed = parse_file(dlm_path) |
| 46 | 45 | assert parsed.frontmatter.training.preference.method == "orpo" |
| 47 | 46 | |
| 48 | - spec = resolve_base_model(parsed.frontmatter.base_model, accept_license=True) | |
| 49 | - plan = doctor().plan | |
| 50 | - if plan is None: | |
| 51 | - pytest.skip("no viable plan on this host — ORPO body needs a real trainer") | |
| 47 | + spec, plan, capabilities = resolve_spec_and_plan( | |
| 48 | + parsed, | |
| 49 | + accept_license=True, | |
| 50 | + skip_reason="no viable plan on this host — ORPO body needs a real trainer", | |
| 51 | + ) | |
| 52 | 52 | |
| 53 | 53 | prior_manifest = load_manifest(store.manifest) |
| 54 | 54 | prior_runs = len(prior_manifest.training_runs) |
@@ -62,7 +62,7 @@ def test_orpo_phase_writes_second_adapter_version(trained_store) -> None: # typ | ||
| 62 | 62 | spec, |
| 63 | 63 | plan, |
| 64 | 64 | phase="preference", |
| 65 | - capabilities=doctor().capabilities, | |
| 65 | + capabilities=capabilities, | |
| 66 | 66 | lock_mode="ignore", |
| 67 | 67 | ) |
| 68 | 68 | assert [r.phase for r in results] == ["preference"] |
tests/integration/watch/test_watch_retrain.pymodified@@ -36,13 +36,12 @@ def test_watch_cycle_detects_new_content_and_retrains( # pragma: no cover - slo | ||
| 36 | 36 | tmp_path: Path, |
| 37 | 37 | ) -> None: |
| 38 | 38 | """`do_one_cycle` on a doc with new content runs the trainer and bumps version.""" |
| 39 | - from dlm.base_models import resolve as resolve_base_model | |
| 40 | 39 | from dlm.doc.parser import parse_file |
| 41 | - from dlm.hardware import doctor | |
| 42 | 40 | from dlm.train.trainer import run as trainer_run |
| 43 | 41 | from dlm.watch.loop import do_one_cycle |
| 42 | + from tests.fixtures.planning import resolve_spec_and_plan | |
| 44 | 43 | |
| 45 | - doc_path = trained_store.doc_path | |
| 44 | + doc_path = trained_store.doc | |
| 46 | 45 | store = trained_store.store |
| 47 | 46 | initial_adapter = store.resolve_current_adapter() |
| 48 | 47 | assert initial_adapter is not None |
@@ -50,15 +49,21 @@ def test_watch_cycle_detects_new_content_and_retrains( # pragma: no cover - slo | ||
| 50 | 49 | # Append a new section to the doc so the ChangeSet sees `new`. |
| 51 | 50 | original = doc_path.read_text(encoding="utf-8") |
| 52 | 51 | doc_path.write_text( |
| 53 | - original + "\n\n## Added by watch test\n\nThis is new content.\n", | |
| 52 | + original | |
| 53 | + + "\n\n::instruction::\n" | |
| 54 | + + "### Q\n" | |
| 55 | + + "What changed in the watch test?\n" | |
| 56 | + + "### A\n" | |
| 57 | + + "A new instruction section was appended.\n", | |
| 54 | 58 | encoding="utf-8", |
| 55 | 59 | ) |
| 56 | 60 | |
| 57 | 61 | parsed = parse_file(doc_path) |
| 58 | - spec = resolve_base_model(parsed.frontmatter.base_model, accept_license=True) | |
| 59 | - plan = doctor(training_config=parsed.frontmatter.training).plan | |
| 60 | - if plan is None: | |
| 61 | - pytest.skip("no viable plan on this host — watch retrain needs a real trainer") | |
| 62 | + spec, plan, _caps = resolve_spec_and_plan( | |
| 63 | + parsed, | |
| 64 | + accept_license=True, | |
| 65 | + skip_reason="no viable plan on this host — watch retrain needs a real trainer", | |
| 66 | + ) | |
| 62 | 67 | |
| 63 | 68 | result = do_one_cycle( |
| 64 | 69 | doc_path=doc_path, |