160 lines
4.3 KiB
Python
160 lines
4.3 KiB
Python
|
|
"""Tests for dynamic plan adjustment."""
|
|||
|
|
|
|||
|
|
import pytest
|
|||
|
|
from datetime import datetime
|
|||
|
|
|
|||
|
|
from src.engines.plan_adjustment import (
|
|||
|
|
adjust_plan,
|
|||
|
|
identify_anomalies,
|
|||
|
|
_fallback_plan_adjustment
|
|||
|
|
)
|
|||
|
|
from src.models.analysis_plan import AnalysisPlan, AnalysisTask
|
|||
|
|
from src.models.analysis_result import AnalysisResult
|
|||
|
|
from src.models.requirement_spec import AnalysisObjective
|
|||
|
|
|
|||
|
|
|
|||
|
|
# Feature: true-ai-agent, Property 8: 计划动态调整
|
|||
|
|
def test_plan_adjustment_with_anomaly():
|
|||
|
|
"""
|
|||
|
|
Property 8: For any analysis plan and intermediate results, if results
|
|||
|
|
contain anomaly findings, the plan adjustment function should be able to
|
|||
|
|
generate new deep-dive tasks or adjust existing task priorities.
|
|||
|
|
|
|||
|
|
Validates: 场景4验收.2, 场景4验收.3, FR-3.3
|
|||
|
|
"""
|
|||
|
|
# Create plan
|
|||
|
|
plan = AnalysisPlan(
|
|||
|
|
objectives=[
|
|||
|
|
AnalysisObjective(
|
|||
|
|
name="数据分析",
|
|||
|
|
description="分析数据",
|
|||
|
|
metrics=[],
|
|||
|
|
priority=3
|
|||
|
|
)
|
|||
|
|
],
|
|||
|
|
tasks=[
|
|||
|
|
AnalysisTask(
|
|||
|
|
id="task_1",
|
|||
|
|
name="Task 1",
|
|||
|
|
description="First task",
|
|||
|
|
priority=3,
|
|||
|
|
status='completed'
|
|||
|
|
),
|
|||
|
|
AnalysisTask(
|
|||
|
|
id="task_2",
|
|||
|
|
name="Task 2",
|
|||
|
|
description="Second task",
|
|||
|
|
priority=3,
|
|||
|
|
status='pending'
|
|||
|
|
)
|
|||
|
|
],
|
|||
|
|
created_at=datetime.now(),
|
|||
|
|
updated_at=datetime.now()
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# Create results with anomaly
|
|||
|
|
results = [
|
|||
|
|
AnalysisResult(
|
|||
|
|
task_id="task_1",
|
|||
|
|
task_name="Task 1",
|
|||
|
|
success=True,
|
|||
|
|
insights=["发现异常:某类别占比90%,远超正常范围"],
|
|||
|
|
execution_time=1.0
|
|||
|
|
)
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
# Adjust plan (using fallback)
|
|||
|
|
adjusted_plan = _fallback_plan_adjustment(plan, results)
|
|||
|
|
|
|||
|
|
# Verify: Plan should be updated
|
|||
|
|
assert adjusted_plan.updated_at >= plan.created_at
|
|||
|
|
|
|||
|
|
# Verify: Pending task priority should be increased
|
|||
|
|
task_2 = next(t for t in adjusted_plan.tasks if t.id == "task_2")
|
|||
|
|
assert task_2.priority >= 3
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_identify_anomalies():
|
|||
|
|
"""Test anomaly identification from results."""
|
|||
|
|
results = [
|
|||
|
|
AnalysisResult(
|
|||
|
|
task_id="task_1",
|
|||
|
|
task_name="Task 1",
|
|||
|
|
success=True,
|
|||
|
|
insights=["发现异常数据", "正常分布"],
|
|||
|
|
execution_time=1.0
|
|||
|
|
),
|
|||
|
|
AnalysisResult(
|
|||
|
|
task_id="task_2",
|
|||
|
|
task_name="Task 2",
|
|||
|
|
success=True,
|
|||
|
|
insights=["一切正常"],
|
|||
|
|
execution_time=1.0
|
|||
|
|
)
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
anomalies = identify_anomalies(results)
|
|||
|
|
|
|||
|
|
# Should identify one anomaly
|
|||
|
|
assert len(anomalies) >= 1
|
|||
|
|
assert anomalies[0]['task_id'] == "task_1"
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_plan_adjustment_no_anomaly():
|
|||
|
|
"""Test plan adjustment when no anomalies found."""
|
|||
|
|
plan = AnalysisPlan(
|
|||
|
|
objectives=[],
|
|||
|
|
tasks=[
|
|||
|
|
AnalysisTask(
|
|||
|
|
id="task_1",
|
|||
|
|
name="Task 1",
|
|||
|
|
description="First task",
|
|||
|
|
priority=3,
|
|||
|
|
status='completed'
|
|||
|
|
)
|
|||
|
|
],
|
|||
|
|
created_at=datetime.now(),
|
|||
|
|
updated_at=datetime.now()
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
results = [
|
|||
|
|
AnalysisResult(
|
|||
|
|
task_id="task_1",
|
|||
|
|
task_name="Task 1",
|
|||
|
|
success=True,
|
|||
|
|
insights=["一切正常"],
|
|||
|
|
execution_time=1.0
|
|||
|
|
)
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
adjusted_plan = _fallback_plan_adjustment(plan, results)
|
|||
|
|
|
|||
|
|
# Should still update timestamp
|
|||
|
|
assert adjusted_plan.updated_at >= plan.created_at
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_identify_anomalies_empty_results():
|
|||
|
|
"""Test anomaly identification with empty results."""
|
|||
|
|
anomalies = identify_anomalies([])
|
|||
|
|
|
|||
|
|
assert anomalies == []
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_identify_anomalies_failed_results():
|
|||
|
|
"""Test that failed results are skipped."""
|
|||
|
|
results = [
|
|||
|
|
AnalysisResult(
|
|||
|
|
task_id="task_1",
|
|||
|
|
task_name="Task 1",
|
|||
|
|
success=False,
|
|||
|
|
error="Failed",
|
|||
|
|
insights=["发现异常"],
|
|||
|
|
execution_time=1.0
|
|||
|
|
)
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
anomalies = identify_anomalies(results)
|
|||
|
|
|
|||
|
|
# Failed results should be skipped
|
|||
|
|
assert len(anomalies) == 0
|