File size: 3,749 Bytes
20c251e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from __future__ import annotations

from pathlib import Path

from dovla_cil.config.schema import (
    DoVLACILConfig,
    apply_cli_overrides,
    load_config,
    load_config_dict,
    save_resolved_config,
)


def test_load_default_config() -> None:
    config = load_config()
    assert isinstance(config, DoVLACILConfig)
    assert config.sim.backend == "toy"
    assert config.sim.seed == 0
    assert config.sim.params == {}
    assert config.generation.backend == "toy"
    assert config.generation.k > 0


def test_env_overrides(monkeypatch) -> None:
    monkeypatch.setenv("DOVLA_CIL_GENERATION__K", "12")
    monkeypatch.setenv("DOVLA_CIL_SIM__SEED", "42")
    monkeypatch.setenv("OPENCLAUDE_MODEL", "mock-model")
    config = load_config()
    assert config.generation.k == 12
    assert config.sim.seed == 42
    assert config.vlm.model == "mock-model"


def test_config_file_loads() -> None:
    config = load_config("configs/toy/generate_cil_k4.yaml")

    assert config.generation.k == 4
    assert config.generation.output_dir == "outputs/config_toy/cil_k4"
    assert config.sim.backend == "toy"


def test_all_experiment_configs_load_as_dicts() -> None:
    paths = sorted(Path("configs").glob("*/*.yaml"))
    assert paths
    for path in paths:
        payload = load_config_dict(path)
        assert isinstance(payload, dict)
        assert "seed" in payload


def test_large_templates_have_safe_defaults() -> None:
    config = load_config("configs/large/generate_cil_maniskill_template.yaml")

    assert config.seed == 0
    assert config.sim.backend == "maniskill"
    assert config.sim.params["env_id"] == "PickCube-v1"
    assert config.generation.output_dir == "data/cil_maniskill_k32"


def test_env_expansion(monkeypatch, tmp_path: Path) -> None:
    config_path = tmp_path / "config.yaml"
    config_path.write_text(
        "generation:\n"
        "  output_dir: ${DOVLA_TMP_ROOT}/cil\n"
        "  k: 4\n",
        encoding="utf-8",
    )
    monkeypatch.setenv("DOVLA_TMP_ROOT", str(tmp_path / "expanded"))

    payload = load_config_dict(config_path)

    assert payload["generation"]["output_dir"] == str(tmp_path / "expanded" / "cil")


def test_env_expansion_default_value(monkeypatch) -> None:
    monkeypatch.delenv("DOVLA_MISSING_ROOT", raising=False)
    payload = load_config_dict(
        "configs/toy/generate_cil_k4.yaml",
        overrides=["generation.output_dir=${DOVLA_MISSING_ROOT:-outputs/fallback}/cil"],
    )

    assert payload["generation"]["output_dir"] == "outputs/fallback/cil"


def test_cli_override_utility() -> None:
    payload = load_config_dict(
        "configs/toy/train_dovla_small.yaml",
        overrides=["training.epochs=3", "model.hidden_dim=96", "sim.params.foo=bar", "sim.params.enabled=true"],  # noqa: E501
    )
    config = DoVLACILConfig.from_dict(payload)

    assert config.training.epochs == 3
    assert config.model.hidden_dim == 96
    assert config.sim.params["foo"] == "bar"
    assert config.sim.params["enabled"] is True


def test_typed_loader_accepts_cli_overrides() -> None:
    config = load_config(
        "configs/toy/train_dovla_small.yaml",
        overrides=["training.epochs=2", "model.hidden_dim=80"],
    )

    assert config.training.epochs == 2
    assert config.model.hidden_dim == 80


def test_apply_cli_overrides_and_save_resolved(tmp_path: Path) -> None:
    payload = {"training": {"epochs": 1}, "paths": {"out": "${HOME}/runs"}}
    apply_cli_overrides(payload, ["training.epochs=2", "paths.out=/tmp/run"])

    path = save_resolved_config(payload, tmp_path)

    assert payload["training"]["epochs"] == 2
    assert payload["paths"]["out"] == "/tmp/run"
    assert path == tmp_path / "resolved_config.yaml"
    assert path.exists()