Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,16 @@ tensorboard --logdir runs/{env-name}
python -m pytest
```

### 提交前检查

push / 提交 PR 前,先在本地跑一次 pre-commit 钩子(ruff check、ruff format 等),确保 CI 不因 lint 失败空转:

```bash
prek run --all-files
```

若 hook 自动修改了文件,将修改并入提交后再 push。

## 架构要点

- **Backend 无关 core**:`motrix_env_core` 不 import 任何 simulator;前端只通过 `motrix_env_core.sim.registry` 解析 backend。
Expand Down
36 changes: 31 additions & 5 deletions motrix_env_core/tests/test_numba_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,33 @@ def _compile_manager(env: ManagerEnv):
return NumbaKernelCompiler(env).build()


@pytest.fixture(autouse=True)
# Share a single on-disk cache directory across the whole test module (hermetic,
# never touches the user cache), but do not clear the in-process kernel caches:
# each distinct plan is compiled once instead of per-test full recompilation
# caused by cache-clearing autouse fixtures (issue #32).
@pytest.fixture(autouse=True, scope="module")
def _shared_numba_cache_dir(tmp_path_factory):
monkeypatch = pytest.MonkeyPatch()
monkeypatch.setenv("NUMBA_CACHE_DIR", str(tmp_path_factory.mktemp("numba-cache")))
yield
monkeypatch.undo()


# Referenced explicitly only by tests that verify cache isolation behavior:
# clear in-process caches and use a separate empty disk cache, restoring the
# shared caches afterwards so later tests are not order-dependent.
@pytest.fixture
def _isolated_numba_cache(tmp_path, monkeypatch):
monkeypatch.setenv("NUMBA_CACHE_DIR", str(tmp_path / "numba-cache"))
saved_kernel_cache = dict(compiler_module._KERNEL_CACHE)
saved_term_cache = dict(compiler_module._TERM_CACHE)
compiler_module._KERNEL_CACHE.clear()
compiler_module._TERM_CACHE.clear()
yield
compiler_module._KERNEL_CACHE.clear()
compiler_module._KERNEL_CACHE.update(saved_kernel_cache)
compiler_module._TERM_CACHE.clear()
compiler_module._TERM_CACHE.update(saved_term_cache)


_GROUPS = _manager_groups()
Expand Down Expand Up @@ -432,7 +454,7 @@ def record_read() -> None:
assert read_count == 1


def test_reset_descriptor_is_part_of_numba_kernel_cache_key() -> None:
def test_reset_descriptor_is_part_of_numba_kernel_cache_key(_isolated_numba_cache) -> None:
first = ManagerEnv(
_ManagerEnvCfg(sim_reset=_DescriptorManagerResetCfg(term=_DescriptorResetTermCfg(tag="first"))),
num_envs=1,
Expand Down Expand Up @@ -738,7 +760,9 @@ def test_post_reset_observation_does_not_run_command_evaluation() -> None:
np.testing.assert_allclose(state.obs.policy[:, 2], [0.5, 1.0, 1.5])


def test_materialize_source_is_safe_for_concurrent_same_plan_writers(tmp_path, monkeypatch) -> None:
def test_materialize_source_is_safe_for_concurrent_same_plan_writers(
_isolated_numba_cache, tmp_path, monkeypatch
) -> None:
monkeypatch.setenv("NUMBA_CACHE_DIR", str(tmp_path))
source = "generated = True\\n"

Expand All @@ -753,7 +777,7 @@ def materialize(_: int) -> str:
assert not list((tmp_path / "generated").glob("*.tmp"))


def test_build_rematerializes_source_after_cache_invalidation(monkeypatch, tmp_path) -> None:
def test_build_rematerializes_source_after_cache_invalidation(_isolated_numba_cache, monkeypatch, tmp_path) -> None:
monkeypatch.setenv("NUMBA_CACHE_DIR", str(tmp_path))
compiler_module._KERNEL_CACHE.clear()
env = _ManagerEnv(num_envs=1)
Expand All @@ -774,7 +798,9 @@ def compile_kernels(source, filename):
compiler_module._KERNEL_CACHE.pop(compiled.layout.plan_key, None)


def test_specialization_cache_failure_rebuilds_callable_dispatchers_before_retry(monkeypatch) -> None:
def test_specialization_cache_failure_rebuilds_callable_dispatchers_before_retry(
_isolated_numba_cache, monkeypatch
) -> None:
env = _ManagerEnv(num_envs=1)
invalidated = []
compile_attempts = []
Expand Down
Loading