84 lines
3.0 KiB
Python
84 lines
3.0 KiB
Python
"""P1 交付回归:benchmark manifest/真值隔离、纯时间奖励与 project 兼容层。
|
|
|
|
这些测试不训练神经网络,只验证评测入口和接口契约;重训练属于 smoke 手测。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import importlib.util
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
np = pytest.importorskip("numpy")
|
|
pytest.importorskip("referee")
|
|
|
|
from mcm26b.config import ProblemConfig
|
|
|
|
|
|
def _benchmark_module():
|
|
path = Path(__file__).parents[1] / "scripts" / "benchmark_hrl.py"
|
|
spec = importlib.util.spec_from_file_location("benchmark_hrl_p1", path)
|
|
module = importlib.util.module_from_spec(spec)
|
|
assert spec.loader is not None
|
|
sys.modules[spec.name] = module
|
|
try:
|
|
spec.loader.exec_module(module)
|
|
finally:
|
|
pass
|
|
return module
|
|
|
|
|
|
def test_manifest_roundtrip_and_truth_summary():
|
|
module = _benchmark_module()
|
|
manifest = module.make_default_manifest(
|
|
problem=3, scenes=2, sources=3, directional=0,
|
|
start_seed=123, config=ProblemConfig())
|
|
scenes = module.scenes_from_manifest(manifest)
|
|
assert [scene.scene_id for scene in scenes] == ["scene-123", "scene-124"]
|
|
assert all(scene.truth_channels for scene in scenes)
|
|
assert all(1 <= channel <= 20 for scene in scenes
|
|
for channel in scene.truth_channels)
|
|
|
|
|
|
def test_benchmark_heuristic_is_valid_and_truth_isolated(tmp_path):
|
|
module = _benchmark_module()
|
|
manifest = module.make_default_manifest(
|
|
problem=3, scenes=1, sources=3, directional=0,
|
|
start_seed=777, config=ProblemConfig())
|
|
scene = module.scenes_from_manifest(manifest)[0]
|
|
run_dir = tmp_path / "run"
|
|
result = module.run_scene_variant(
|
|
scene, "hrl_heuristic", config=ProblemConfig(), hrl_model=None,
|
|
run_dir=run_dir)
|
|
row = result["row"]
|
|
assert row["valid"] is True
|
|
assert row["cleared_count"] == len(scene.truth_channels) == 3
|
|
assert row["cleared_matches_truth"] is True
|
|
assert row["no_source_declared_absent"] is True
|
|
assert (run_dir / "session.jsonl").exists()
|
|
# manifest/run summary 中不出现策略可消费的 simulator.sources 真值对象。
|
|
assert "sources" not in row
|
|
|
|
|
|
def test_time_only_reward_has_no_per_source_shaping():
|
|
from mcm26b.hrl.hierarchical_env import HRLReward
|
|
reward = HRLReward.time_only()
|
|
assert reward.clear == 0.0
|
|
assert reward.detect == 0.0
|
|
assert reward.info_weight == 0.0
|
|
assert reward.time_scale == 100.0
|
|
assert reward.failure >= 3600.0
|
|
|
|
|
|
@pytest.mark.skipif(importlib.util.find_spec("gymnasium") is None,
|
|
reason="RL 依赖组未安装")
|
|
def test_project_compat_layer_reexports_real_classes():
|
|
from mcm26b.hrl.hierarchical_env import HierarchicalEnv
|
|
from project.env.local_env import HierarchicalEnv as CompatEnv
|
|
from project.env.simulator_client import SimulatorClient
|
|
from project.policies.high_level_ppo import HighLevelPolicy
|
|
assert CompatEnv is HierarchicalEnv
|
|
assert SimulatorClient.__module__ == "mcm26b.protocol.client"
|
|
assert HighLevelPolicy.__module__ == "mcm26b.hrl.policy"
|