初始化
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
"""M7 调度与日报模块单元测试。"""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from scheduler.pipeline import PipelineResult, StepResult
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# StepResult
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
class TestStepResult:
|
||||
"""StepResult 测试。"""
|
||||
|
||||
def test_success_step(self):
|
||||
sr = StepResult(name="extract", success=True, elapsed_sec=5.0, message="17 篇")
|
||||
assert sr.name == "extract"
|
||||
assert sr.success
|
||||
assert sr.message == "17 篇"
|
||||
|
||||
def test_failed_step(self):
|
||||
sr = StepResult(name="translate", success=False, elapsed_sec=30.0,
|
||||
message="API timeout")
|
||||
assert not sr.success
|
||||
assert "timeout" in sr.message
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# PipelineResult
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
class TestPipelineResult:
|
||||
"""PipelineResult 测试。"""
|
||||
|
||||
def test_all_success(self):
|
||||
result = PipelineResult(steps=[
|
||||
StepResult(name="extract", success=True, elapsed_sec=1.0),
|
||||
StepResult(name="dedup", success=True, elapsed_sec=0.5),
|
||||
])
|
||||
assert result.all_success
|
||||
assert result.success_count == 2
|
||||
|
||||
def test_partial_failure(self):
|
||||
result = PipelineResult(steps=[
|
||||
StepResult(name="extract", success=True, elapsed_sec=1.0),
|
||||
StepResult(name="translate", success=False, elapsed_sec=30.0),
|
||||
StepResult(name="embed", success=True, elapsed_sec=2.0),
|
||||
])
|
||||
assert not result.all_success
|
||||
assert result.success_count == 2
|
||||
|
||||
def test_empty(self):
|
||||
result = PipelineResult()
|
||||
assert result.all_success # 空集合 vacuously true
|
||||
assert result.success_count == 0
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# run_pipeline(mock 各模块)
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
class TestRunPipeline:
|
||||
"""run_pipeline 测试(mock 各步骤)。"""
|
||||
|
||||
@patch("scheduler.pipeline.run_step_extract")
|
||||
@patch("scheduler.pipeline.run_step_dedup")
|
||||
@patch("scheduler.pipeline.run_step_embed")
|
||||
@patch("scheduler.pipeline.run_step_index")
|
||||
def test_pipeline_runs_all_steps(self, mock_idx, mock_emb, mock_dedup, mock_ext):
|
||||
from scheduler.pipeline import run_pipeline
|
||||
|
||||
mock_ext.return_value = StepResult(name="extract", success=True, elapsed_sec=1)
|
||||
mock_dedup.return_value = StepResult(name="dedup", success=True, elapsed_sec=1)
|
||||
mock_emb.return_value = StepResult(name="embed", success=True, elapsed_sec=1)
|
||||
mock_idx.return_value = StepResult(name="index", success=True, elapsed_sec=1)
|
||||
|
||||
result = run_pipeline("20260621", skip_report=True)
|
||||
assert result.success_count >= 4
|
||||
|
||||
@patch("scheduler.pipeline.run_step_extract")
|
||||
@patch("scheduler.pipeline.run_step_dedup")
|
||||
def test_pipeline_continues_on_failure(self, mock_dedup, mock_ext):
|
||||
from scheduler.pipeline import run_pipeline
|
||||
|
||||
mock_ext.return_value = StepResult(name="extract", success=False, elapsed_sec=1,
|
||||
message="error")
|
||||
mock_dedup.return_value = StepResult(name="dedup", success=True, elapsed_sec=1)
|
||||
|
||||
result = run_pipeline("20260621", steps=["extract", "dedup"], skip_report=True)
|
||||
# extract 失败但 dedup 仍然执行
|
||||
assert result.success_count == 1
|
||||
|
||||
def test_unknown_step_skipped(self):
|
||||
from scheduler.pipeline import run_pipeline
|
||||
result = run_pipeline("20260621", steps=["nonexistent_step"], skip_report=True)
|
||||
assert len(result.steps) == 1
|
||||
assert not result.steps[0].success
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# generate_report(无数据场景)
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
class TestGenerateReport:
|
||||
"""generate_report 测试。"""
|
||||
|
||||
@patch("scheduler.reporter._load_events_window")
|
||||
@patch("scheduler.reporter._collect_stats_window")
|
||||
def test_no_data_returns_none(self, mock_stats, mock_events):
|
||||
from scheduler.reporter import generate_report
|
||||
|
||||
mock_events.return_value = []
|
||||
mock_stats.return_value = {
|
||||
"proc": 0, "deduped": 0, "emb_count": 0,
|
||||
"qdrant_count": 0, "raw_total": 0, "raw_by_source": {},
|
||||
}
|
||||
|
||||
result = generate_report()
|
||||
assert result is None
|
||||
Reference in New Issue
Block a user