test: cover backfill params end-to-end (mutation isolation + seq_offset)
This commit is contained in:
@@ -580,6 +580,90 @@ class TestPipelineV2:
|
|||||||
if result.accepted:
|
if result.accepted:
|
||||||
assert len(result.heavy_sampled) == len(result.accepted)
|
assert len(result.heavy_sampled) == len(result.accepted)
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_backfill_params_do_not_mutate_caller_objects(
|
||||||
|
self, tree, default_config, store, tmp_path
|
||||||
|
):
|
||||||
|
"""补生成三参:传入的 used_node_ids / embed_pool 对象不被就地修改。
|
||||||
|
|
||||||
|
内部应复制而非别名 —— run 完之后调用方传入的容器长度/内容保持原样。
|
||||||
|
"""
|
||||||
|
vlm = MockVLM([_make_candidate_json(f"Q{i}?") for i in range(20)])
|
||||||
|
llm = MockLLM([_make_gate_pass_response()] * 100)
|
||||||
|
|
||||||
|
config = PipelineConfig(
|
||||||
|
per_type=2,
|
||||||
|
retry_limit=2,
|
||||||
|
heavy_sample_rate=0.0,
|
||||||
|
dedup_threshold=0.85,
|
||||||
|
concurrency=1,
|
||||||
|
seed=42,
|
||||||
|
output_dir=tmp_path / "out",
|
||||||
|
)
|
||||||
|
|
||||||
|
initial_used_node_ids = {"some_node"}
|
||||||
|
seed_vec = _mock_embed_fn("seed embedding text")
|
||||||
|
initial_embed_pool = [seed_vec]
|
||||||
|
|
||||||
|
result = await run_pipeline_v2(
|
||||||
|
video_ids=["vid_L1_000"],
|
||||||
|
trees={"vid_L1_000": tree},
|
||||||
|
vlm=vlm,
|
||||||
|
llm=llm,
|
||||||
|
embed_fn=_mock_embed_fn,
|
||||||
|
store=store,
|
||||||
|
config=config,
|
||||||
|
task_types=["Action Recognition"],
|
||||||
|
initial_used_node_ids=initial_used_node_ids,
|
||||||
|
initial_embed_pool=initial_embed_pool,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 至少接受一题,确保内部确实往副本里追加了 node/embedding
|
||||||
|
assert len(result.accepted) > 0
|
||||||
|
|
||||||
|
# 调用方对象未被 mutation:集合仍只含原始节点
|
||||||
|
assert initial_used_node_ids == {"some_node"}
|
||||||
|
# embed_pool 仍只含最初的一个向量,且内容未变
|
||||||
|
assert len(initial_embed_pool) == 1
|
||||||
|
assert np.array_equal(initial_embed_pool[0], seed_vec)
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_seq_offset_continues_question_ids(
|
||||||
|
self, tree, default_config, store, tmp_path
|
||||||
|
):
|
||||||
|
"""补生成三参:seq_offset 端到端续编 question_id 的 seq,避开旧 run 号段。"""
|
||||||
|
vlm = MockVLM([_make_candidate_json(f"Q{i}?") for i in range(20)])
|
||||||
|
llm = MockLLM([_make_gate_pass_response()] * 100)
|
||||||
|
|
||||||
|
config = PipelineConfig(
|
||||||
|
per_type=2,
|
||||||
|
retry_limit=2,
|
||||||
|
heavy_sample_rate=0.0,
|
||||||
|
dedup_threshold=0.85,
|
||||||
|
concurrency=1,
|
||||||
|
seed=42,
|
||||||
|
output_dir=tmp_path / "out",
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await run_pipeline_v2(
|
||||||
|
video_ids=["vid_L1_000"],
|
||||||
|
trees={"vid_L1_000": tree},
|
||||||
|
vlm=vlm,
|
||||||
|
llm=llm,
|
||||||
|
embed_fn=_mock_embed_fn,
|
||||||
|
store=store,
|
||||||
|
config=config,
|
||||||
|
task_types=["Action Recognition"],
|
||||||
|
seq_offset=30,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(result.accepted) > 0
|
||||||
|
# question_id 格式 "{video_id}_{task_type}_{seq:04d}",seq 是最后一段 4 位数字
|
||||||
|
seqs = [int(q.question_id.rsplit("_", 1)[1]) for q in result.accepted]
|
||||||
|
assert all(s > 30 for s in seqs), seqs
|
||||||
|
# per_type=2 → seq 从 31 起续编,不与 0-30 撞
|
||||||
|
assert min(seqs) == 31
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_store_records_all(self, tree, default_config, store, tmp_path):
|
async def test_store_records_all(self, tree, default_config, store, tmp_path):
|
||||||
"""验证 store 中记录了每道题的生成与门控结果。"""
|
"""验证 store 中记录了每道题的生成与门控结果。"""
|
||||||
|
|||||||
Reference in New Issue
Block a user