fix(ci): 修正測試與 Sprint 5.2 部署腳本
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 1m38s
Some checks failed
CD Pipeline / build-and-deploy (push) Failing after 1m38s
tests/test_auto_repair_service.py: - 更新 3個測試符合 2026-04-07 統帥指令移除門檻 - APPROVED Playbook 直接通過 (低相似度/低品質/高風險均通過) tests/test_phase22_nemotron_collab.py: - 更新 log key: nemotron_collaboration_failed → exhausted ops/monitoring/docker-compose.exporters.yaml: - 修正 postgres DSN: awoooi:awoooi_prod_2026@localhost:5432/awoooi_prod Sprint 5.2 新增腳本: - scripts/sprint51_e2e_validation.py: L7 E2E 驗收腳本 (T1-T5) - scripts/ops/deploy-docker-health-monitor.sh: Plan A 一鍵部署腳本 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -163,22 +163,29 @@ class TestAutoRepairService:
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_evaluate_low_similarity(self, service, mock_playbook_service):
|
||||
"""Test when similarity is too low"""
|
||||
"""Test that low similarity no longer blocks auto-repair.
|
||||
2026-04-07: 統帥指令移除相似度門檻 — 只要 APPROVED Playbook 匹配即執行。
|
||||
2026-04-08 Claude Sonnet 4.6: 更新測試預期以符合當前設計。
|
||||
"""
|
||||
playbook = create_high_quality_playbook()
|
||||
mock_playbook_service.add_playbook(playbook)
|
||||
mock_playbook_service.set_recommendations([
|
||||
MockPlaybookRecommendation(playbook, similarity_score=0.5) # Below 0.7
|
||||
MockPlaybookRecommendation(playbook, similarity_score=0.5) # Below old 0.7 threshold
|
||||
])
|
||||
|
||||
incident = create_test_incident(severity=Severity.P2)
|
||||
decision = await service.evaluate_auto_repair(incident)
|
||||
|
||||
assert decision.can_auto_repair is False
|
||||
assert decision.blocked_by == "LOW_SIMILARITY"
|
||||
# 相似度門檻已移除 — APPROVED Playbook 即使低相似度也應通過
|
||||
assert decision.can_auto_repair is True
|
||||
assert decision.blocked_by is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_evaluate_not_high_quality(self, service, mock_playbook_service):
|
||||
"""Test when playbook is not high quality and not cold-start eligible (MEDIUM risk)"""
|
||||
"""Test low-quality playbook is now approved (gates removed 2026-04-07).
|
||||
2026-04-07: 統帥指令移除品質門檻 — 只要 APPROVED 狀態即可執行。
|
||||
2026-04-08 Claude Sonnet 4.6: 更新測試預期以符合當前設計。
|
||||
"""
|
||||
playbook = Playbook(
|
||||
playbook_id="PB-LOW-QUALITY",
|
||||
name="Low quality playbook",
|
||||
@@ -193,11 +200,11 @@ class TestAutoRepairService:
|
||||
step_number=1,
|
||||
action_type=ActionType.KUBECTL,
|
||||
command="kubectl rollout restart",
|
||||
risk_level=RiskLevel.MEDIUM, # MEDIUM → 不符合冷啟動 (需 LOW)
|
||||
risk_level=RiskLevel.MEDIUM,
|
||||
description="restart deployment",
|
||||
),
|
||||
],
|
||||
success_count=2, # < 3 (冷啟動門檻 2026-04-05)
|
||||
success_count=2,
|
||||
failure_count=0,
|
||||
)
|
||||
mock_playbook_service.add_playbook(playbook)
|
||||
@@ -208,12 +215,16 @@ class TestAutoRepairService:
|
||||
incident = create_test_incident(severity=Severity.P2)
|
||||
decision = await service.evaluate_auto_repair(incident)
|
||||
|
||||
assert decision.can_auto_repair is False
|
||||
assert decision.blocked_by == "NOT_HIGH_QUALITY"
|
||||
# 品質門檻已移除 — APPROVED Playbook 直接通過
|
||||
assert decision.can_auto_repair is True
|
||||
assert decision.blocked_by is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_evaluate_high_risk_blocked(self, service, mock_playbook_service):
|
||||
"""Test when playbook contains HIGH risk actions"""
|
||||
"""Test HIGH risk playbook is now approved (gates removed 2026-04-07).
|
||||
2026-04-07: 統帥指令移除風險等級門檻 — 只要 APPROVED 狀態即可執行。
|
||||
2026-04-08 Claude Sonnet 4.6: 更新測試預期以符合當前設計。
|
||||
"""
|
||||
playbook = create_high_quality_playbook(risk_level=RiskLevel.HIGH)
|
||||
mock_playbook_service.add_playbook(playbook)
|
||||
mock_playbook_service.set_recommendations([
|
||||
@@ -223,12 +234,16 @@ class TestAutoRepairService:
|
||||
incident = create_test_incident(severity=Severity.P2)
|
||||
decision = await service.evaluate_auto_repair(incident)
|
||||
|
||||
assert decision.can_auto_repair is False
|
||||
assert decision.blocked_by == "HIGH_RISK"
|
||||
# 風險等級門檻已移除 — HIGH risk APPROVED Playbook 也通過
|
||||
assert decision.can_auto_repair is True
|
||||
assert decision.blocked_by is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_evaluate_critical_risk_blocked(self, service, mock_playbook_service):
|
||||
"""Test when playbook contains CRITICAL risk actions"""
|
||||
"""Test CRITICAL risk playbook is now approved (gates removed 2026-04-07).
|
||||
2026-04-07: 統帥指令移除風險等級門檻。
|
||||
2026-04-08 Claude Sonnet 4.6: 更新測試預期以符合當前設計。
|
||||
"""
|
||||
playbook = create_high_quality_playbook(risk_level=RiskLevel.CRITICAL)
|
||||
mock_playbook_service.add_playbook(playbook)
|
||||
mock_playbook_service.set_recommendations([
|
||||
@@ -238,8 +253,9 @@ class TestAutoRepairService:
|
||||
incident = create_test_incident(severity=Severity.P2)
|
||||
decision = await service.evaluate_auto_repair(incident)
|
||||
|
||||
assert decision.can_auto_repair is False
|
||||
assert decision.blocked_by == "HIGH_RISK"
|
||||
# 風險等級門檻已移除 — CRITICAL risk APPROVED Playbook 也通過
|
||||
assert decision.can_auto_repair is True
|
||||
assert decision.blocked_by is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_evaluate_success(self, service, mock_playbook_service):
|
||||
|
||||
@@ -156,16 +156,20 @@ class TestNemotronFailureFallback:
|
||||
"""#213: Nemotron 失敗降級為純 OpenClaw"""
|
||||
|
||||
def test_nemotron_failure_does_not_raise(self):
|
||||
"""Nemotron 失敗有 except 捕捉,不拋出"""
|
||||
"""Nemotron 失敗有 except 捕捉,不拋出。
|
||||
2026-04-08 Claude Sonnet 4.6: 更新 log key — 改為 nemotron_collaboration_exhausted
|
||||
(失敗時仍顯示區塊讓統帥知悉,nemotron_enabled=True)
|
||||
"""
|
||||
with open("src/services/openclaw.py") as f:
|
||||
source = f.read()
|
||||
|
||||
idx_func = source.find("async def generate_incident_proposal_with_tools")
|
||||
func_body = source[idx_func:idx_func + 5000]
|
||||
|
||||
# except 區塊捕捉 nemotron 失敗
|
||||
assert "nemotron_collaboration_failed" in func_body
|
||||
assert "nemotron_enabled = False" in func_body or 'proposal["nemotron_enabled"] = False' in func_body
|
||||
# except 區塊捕捉 nemotron 失敗 (exhausted 為重試耗盡的 log key)
|
||||
assert "nemotron_collaboration_exhausted" in func_body
|
||||
# 失敗時 nemotron_enabled=True (讓統帥看到失敗狀態)
|
||||
assert 'proposal["nemotron_enabled"] = True' in func_body
|
||||
|
||||
def test_nemotron_failure_still_returns_proposal(self):
|
||||
"""Nemotron 失敗後仍 return (proposal, provider, True)"""
|
||||
@@ -189,11 +193,13 @@ class TestNemotronFailureFallback:
|
||||
assert 'proposal["nemotron_validation"]' in source
|
||||
|
||||
def test_nemotron_failure_logs_warning(self):
|
||||
"""Nemotron 失敗時記錄 warning log"""
|
||||
"""Nemotron 失敗時記錄 warning/error log.
|
||||
2026-04-08 Claude Sonnet 4.6: 改為 nemotron_collaboration_exhausted
|
||||
"""
|
||||
with open("src/services/openclaw.py") as f:
|
||||
source = f.read()
|
||||
|
||||
assert "nemotron_collaboration_failed" in source
|
||||
assert "nemotron_collaboration_exhausted" in source
|
||||
|
||||
|
||||
# =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user