| """Tests for release/readiness helper scripts.""" |
|
|
| from __future__ import annotations |
|
|
| import importlib.util |
| import json |
| from pathlib import Path |
|
|
| import pytest |
|
|
| pytestmark = pytest.mark.fast |
|
|
|
|
| def _load_script_module(name: str, path: Path): |
| spec = importlib.util.spec_from_file_location(name, path) |
| assert spec is not None |
| assert spec.loader is not None |
| module = importlib.util.module_from_spec(spec) |
| spec.loader.exec_module(module) |
| return module |
|
|
|
|
| def test_run_eval_dataset_threshold_reasons(): |
| project_root = Path(__file__).resolve().parents[1] |
| module = _load_script_module("run_eval_dataset_script", project_root / "scripts" / "run_eval_dataset.py") |
|
|
| summary = module._evaluate_results( |
| dataset_path=Path("dataset.json"), |
| results=[{"id": "a", "passed": True}, {"id": "b", "passed": False}, {"id": "c", "passed": True}], |
| strict=False, |
| min_pass_rate=0.9, |
| max_failed=0, |
| min_cases=None, |
| duplicate_ids=[], |
| missing_expected_tools_ids=[], |
| ) |
| assert summary["accepted"] is False |
| assert "pass_rate_below_threshold" in summary["failure_reasons"] |
| assert "failed_count_above_threshold" in summary["failure_reasons"] |
|
|
| strict_summary = module._evaluate_results( |
| dataset_path=Path("dataset.json"), |
| results=[{"id": "a", "passed": True}, {"id": "b", "passed": False}], |
| strict=True, |
| min_pass_rate=None, |
| max_failed=None, |
| min_cases=None, |
| duplicate_ids=[], |
| missing_expected_tools_ids=[], |
| ) |
| assert strict_summary["accepted"] is False |
| assert "strict_failed_cases" in strict_summary["failure_reasons"] |
|
|
| contract_summary = module._evaluate_results( |
| dataset_path=Path("dataset.json"), |
| results=[{"id": "a", "passed": True}], |
| strict=True, |
| min_pass_rate=None, |
| max_failed=None, |
| min_cases=2, |
| duplicate_ids=["a"], |
| missing_expected_tools_ids=["a"], |
| ) |
| assert contract_summary["accepted"] is False |
| assert "insufficient_case_count" in contract_summary["failure_reasons"] |
| assert "duplicate_case_ids" in contract_summary["failure_reasons"] |
| assert "missing_expected_tools" in contract_summary["failure_reasons"] |
|
|
|
|
| def test_run_router_policy_eval_threshold_reasons(): |
| project_root = Path(__file__).resolve().parents[1] |
| module = _load_script_module( |
| "run_router_policy_eval_script", |
| project_root / "scripts" / "run_router_policy_eval.py", |
| ) |
|
|
| row = module._evaluate_case( |
| { |
| "id": "router_case", |
| "expected_route": {"starting_agent": "safety", "route_confidence": 0.4}, |
| "actual_route": {"starting_agent": "action", "route_confidence": 1.2}, |
| "max_confidence": 0.9, |
| } |
| ) |
| assert row["passed"] is False |
| assert "invalid_route_confidence" in row["validation_errors"] |
| assert any("starting_agent" in item for item in row["mismatches"]) |
|
|
| summary = module._evaluate_results( |
| dataset_path=Path("router-dataset.json"), |
| results=[{"id": "a", "passed": True}, {"id": "b", "passed": False}], |
| strict=True, |
| min_pass_rate=1.0, |
| max_failed=0, |
| min_cases=3, |
| duplicate_ids=["b"], |
| ) |
| assert summary["accepted"] is False |
| assert "strict_failed_cases" in summary["failure_reasons"] |
| assert "pass_rate_below_threshold" in summary["failure_reasons"] |
| assert "failed_count_above_threshold" in summary["failure_reasons"] |
| assert "insufficient_case_count" in summary["failure_reasons"] |
| assert "duplicate_case_ids" in summary["failure_reasons"] |
|
|
|
|
| def test_run_interruption_route_eval_threshold_reasons(): |
| project_root = Path(__file__).resolve().parents[1] |
| module = _load_script_module( |
| "run_interruption_route_eval_script", |
| project_root / "scripts" / "run_interruption_route_eval.py", |
| ) |
|
|
| row = module._evaluate_case( |
| { |
| "id": "interruption_case", |
| "expected_route": {"strategy": "resume", "route_confidence": 0.7}, |
| "actual_route": {"strategy": "unknown", "route_confidence": 1.2}, |
| "max_confidence": 0.9, |
| } |
| ) |
| assert row["passed"] is False |
| assert "invalid_strategy" in row["validation_errors"] |
| assert any("strategy" in item for item in row["mismatches"]) |
|
|
| summary = module._evaluate_results( |
| dataset_path=Path("interruption-dataset.json"), |
| results=[{"id": "a", "passed": True}, {"id": "b", "passed": False}], |
| strict=True, |
| min_pass_rate=1.0, |
| max_failed=0, |
| min_cases=3, |
| duplicate_ids=["b"], |
| ) |
| assert summary["accepted"] is False |
| assert "strict_failed_cases" in summary["failure_reasons"] |
| assert "pass_rate_below_threshold" in summary["failure_reasons"] |
| assert "failed_count_above_threshold" in summary["failure_reasons"] |
| assert "insufficient_case_count" in summary["failure_reasons"] |
| assert "duplicate_case_ids" in summary["failure_reasons"] |
|
|
|
|
| def test_run_trace_trajectory_eval_threshold_reasons(): |
| project_root = Path(__file__).resolve().parents[1] |
| module = _load_script_module( |
| "run_trace_trajectory_eval_script", |
| project_root / "scripts" / "run_trace_trajectory_eval.py", |
| ) |
|
|
| row = module._evaluate_case( |
| { |
| "id": "trajectory_case", |
| "trace": [ |
| {"turn_id": 1, "intent": "answer", "response_success": False}, |
| { |
| "turn_id": 2, |
| "intent": "answer", |
| "response_success": False, |
| "interruption_route": {"strategy": "resume"}, |
| "parent_turn_id": 1, |
| }, |
| ], |
| "min_total_score": 0.95, |
| } |
| ) |
| assert row["passed"] is False |
| assert any("total_score below min" in item for item in row["mismatches"]) |
|
|
| summary = module._evaluate_results( |
| dataset_path=Path("trajectory-dataset.json"), |
| results=[{"id": "a", "passed": True}, {"id": "b", "passed": False}], |
| strict=True, |
| min_pass_rate=1.0, |
| max_failed=0, |
| min_cases=3, |
| duplicate_ids=["b"], |
| ) |
| assert summary["accepted"] is False |
| assert "strict_failed_cases" in summary["failure_reasons"] |
| assert "pass_rate_below_threshold" in summary["failure_reasons"] |
| assert "failed_count_above_threshold" in summary["failure_reasons"] |
| assert "insufficient_case_count" in summary["failure_reasons"] |
| assert "duplicate_case_ids" in summary["failure_reasons"] |
|
|
|
|
| def test_run_autonomy_cycle_eval_threshold_reasons(): |
| project_root = Path(__file__).resolve().parents[1] |
| module = _load_script_module( |
| "run_autonomy_cycle_eval_script", |
| project_root / "scripts" / "run_autonomy_cycle_eval.py", |
| ) |
|
|
| row = module._evaluate_case( |
| { |
| "id": "autonomy_case", |
| "actual_cycle": {"replan_count": 2, "retry_scheduled_count": -1}, |
| "actual_status": { |
| "needs_replan_count": 0, |
| "retry_pending_count": 0, |
| "backlog_step_count": 1, |
| "status_counts": {"scheduled": 1}, |
| "failure_taxonomy": {"condition_equals_mismatch": 2}, |
| }, |
| "max_replan_count": 1, |
| } |
| ) |
| assert row["passed"] is False |
| assert "invalid_cycle_retry_scheduled_count" in row["validation_errors"] |
| assert any("replan_count above max" in item for item in row["mismatches"]) |
|
|
| summary = module._evaluate_results( |
| dataset_path=Path("autonomy-dataset.json"), |
| results=[{"id": "a", "passed": True}, {"id": "b", "passed": False}], |
| strict=True, |
| min_pass_rate=1.0, |
| max_failed=0, |
| min_cases=3, |
| duplicate_ids=["b"], |
| ) |
| assert summary["accepted"] is False |
| assert "strict_failed_cases" in summary["failure_reasons"] |
| assert "pass_rate_below_threshold" in summary["failure_reasons"] |
| assert "failed_count_above_threshold" in summary["failure_reasons"] |
| assert "insufficient_case_count" in summary["failure_reasons"] |
| assert "duplicate_case_ids" in summary["failure_reasons"] |
|
|
|
|
| def test_run_runtime_outcome_gate_threshold_reasons(): |
| project_root = Path(__file__).resolve().parents[1] |
| module = _load_script_module( |
| "run_runtime_outcome_gate_script", |
| project_root / "scripts" / "run_runtime_outcome_gate.py", |
| ) |
|
|
| summary = module._evaluate_results( |
| results=[{"id": "a", "passed": True}, {"id": "b", "passed": False}], |
| strict=True, |
| min_pass_rate=1.0, |
| max_failed=0, |
| ) |
| assert summary["accepted"] is False |
| assert "strict_failed_cases" in summary["failure_reasons"] |
| assert "pass_rate_below_threshold" in summary["failure_reasons"] |
| assert "failed_count_above_threshold" in summary["failure_reasons"] |
|
|
|
|
| def test_run_memory_quality_eval_threshold_reasons(): |
| project_root = Path(__file__).resolve().parents[1] |
| module = _load_script_module( |
| "run_memory_quality_eval_script", |
| project_root / "scripts" / "run_memory_quality_eval.py", |
| ) |
|
|
| summary = module._evaluate_results( |
| dataset_path=Path("memory-quality-dataset.json"), |
| results=[ |
| {"id": "a", "passed": True, "llm_judge": {"score": 0.9}}, |
| {"id": "b", "passed": False, "llm_judge": {"score": 0.2}}, |
| ], |
| strict=True, |
| min_pass_rate=0.95, |
| max_failed=0, |
| min_cases=3, |
| duplicate_ids=["a"], |
| min_avg_judge_score=0.8, |
| llm_judge_mode="on", |
| llm_judge_enabled=True, |
| conflict_resolution_mode="on", |
| conflict_resolution_enabled=True, |
| ) |
| assert summary["accepted"] is False |
| assert "strict_failed_cases" in summary["failure_reasons"] |
| assert "pass_rate_below_threshold" in summary["failure_reasons"] |
| assert "failed_count_above_threshold" in summary["failure_reasons"] |
| assert "insufficient_case_count" in summary["failure_reasons"] |
| assert "duplicate_case_ids" in summary["failure_reasons"] |
| assert "avg_judge_score_below_threshold" in summary["failure_reasons"] |
|
|
|
|
| def test_readiness_script_includes_runtime_outcome_gate(): |
| project_root = Path(__file__).resolve().parents[1] |
| script_text = (project_root / "scripts" / "jarvis_readiness.sh").read_text(encoding="utf-8") |
| assert "run_runtime_outcome_gate.py" in script_text |
|
|
|
|
| def test_generate_quality_report_trend(): |
| project_root = Path(__file__).resolve().parents[1] |
| module = _load_script_module("generate_quality_report_script", project_root / "scripts" / "generate_quality_report.py") |
|
|
| baseline = module._build_report( |
| [ |
| {"action": "smart_home", "decision_outcome": "ok"}, |
| {"action": "smart_home", "decision_outcome": "error", "decision_reason": "timeout"}, |
| ] |
| ) |
| report = module._build_report( |
| [ |
| {"action": "smart_home", "decision_outcome": "ok"}, |
| {"action": "todoist_add_task", "decision_outcome": "denied", "decision_reason": "policy"}, |
| {"action": "todoist_add_task", "decision_outcome": "ok"}, |
| ], |
| baseline=baseline, |
| baseline_path="/tmp/baseline.json", |
| ) |
| trend = report["trend"] |
| assert trend["has_baseline"] is True |
| assert trend["baseline_path"] == "/tmp/baseline.json" |
| assert trend["total_events_delta"] == 1 |
| assert trend["failure_count_delta"] == 0 |
| assert isinstance(trend["failure_rate_delta"], float) |
|
|
|
|
| def test_run_soak_profile_live_has_extended_phases_and_artifact_checks(): |
| project_root = Path(__file__).resolve().parents[1] |
| module = _load_script_module("run_soak_profile_script", project_root / "scripts" / "run_soak_profile.py") |
|
|
| live_phases = module._phase_commands("live") |
| phase_names = [name for name, _ in live_phases] |
| assert "sim_baseline" in phase_names |
| assert "fault_network" in phase_names |
| assert "operator_status_contract" in phase_names |
| assert "eval_contract_strict" in phase_names |
|
|
| checks = module._artifact_checks( |
| [ |
| { |
| "phase": "sim_baseline", |
| "status": "passed", |
| "started_at": 1.0, |
| "finished_at": 2.0, |
| "cycle": 1, |
| } |
| ], |
| expected_phase_count_per_cycle=2, |
| repeat=3, |
| ) |
| assert checks["all_status_valid"] is True |
| assert checks["all_timestamps_present"] is True |
| assert checks["phase_names"] == ["sim_baseline"] |
| assert checks["expected_total_phase_count"] == 6 |
| assert checks["cycle_phase_counts"] == {"1": 1} |
|
|
|
|
| def test_run_sim_acceptance_profiles_and_artifact_checks(): |
| project_root = Path(__file__).resolve().parents[1] |
| module = _load_script_module("run_sim_acceptance_script", project_root / "scripts" / "run_sim_acceptance.py") |
|
|
| fast_phases = [name for name, _ in module._phase_commands("fast")] |
| full_phases = [name for name, _ in module._phase_commands("full")] |
| assert "sim_stack_baseline" in fast_phases |
| assert "voice_loop_edges" in fast_phases |
| assert "autonomy_checkpoint_edges" in fast_phases |
| assert "operator_contract_edges" not in fast_phases |
| assert "operator_contract_edges" in full_phases |
| assert "recovery_replay_edges" in full_phases |
|
|
| checks = module._artifact_checks( |
| [ |
| { |
| "phase": "voice_loop_edges", |
| "status": "passed", |
| "started_at": 1.0, |
| "finished_at": 2.0, |
| "cycle": 1, |
| } |
| ], |
| expected_phase_count_per_cycle=3, |
| repeat=2, |
| ) |
| assert checks["all_status_valid"] is True |
| assert checks["all_timestamps_present"] is True |
| assert checks["phase_names"] == ["voice_loop_edges"] |
| assert checks["expected_total_phase_count"] == 6 |
| assert checks["cycle_phase_counts"] == {"1": 1} |
|
|
|
|
| def test_run_fault_campaign_profile_matrix_contract(): |
| project_root = Path(__file__).resolve().parents[1] |
| module = _load_script_module("run_fault_campaign_script", project_root / "scripts" / "run_fault_campaign.py") |
|
|
| assert module._normalize_profiles("all") == ["quick", "network", "storage", "contract"] |
| assert module._normalize_profiles("quick,network,quick") == ["quick", "network"] |
| assert module._profile_tag(["quick", "network"]) == "quick-network" |
| with pytest.raises(ValueError): |
| module._normalize_profiles("quick,invalid") |
|
|
| phases = module._phase_commands(["quick", "storage"]) |
| assert [name for name, _ in phases] == ["fault_quick", "fault_storage"] |
| assert phases[0][1] == ["./scripts/run_fault_profiles.sh", "quick"] |
|
|
|
|
| def test_run_fault_chaos_permutations_and_plan_contract(): |
| project_root = Path(__file__).resolve().parents[1] |
| module = _load_script_module("run_fault_chaos_script", project_root / "scripts" / "run_fault_chaos.py") |
|
|
| assert module._normalize_profiles("quick,network,quick") == ["quick", "network"] |
| with pytest.raises(ValueError): |
| module._normalize_profiles("quick,invalid") |
|
|
| orders = module._permuted_orders(["quick", "network", "storage"], permutations=3) |
| assert orders[0] == ["quick", "network", "storage"] |
| assert orders[1] == ["quick", "storage", "network"] |
| assert len(orders) == 3 |
|
|
| plan = module._phase_plan(orders=orders[:1]) |
| phase_names = [name for name, _ in plan] |
| assert phase_names == [ |
| "fault_quick_p1", |
| "fault_network_p1", |
| "fault_storage_p1", |
| "recovery_idempotence_p1", |
| ] |
|
|
| checks = module._artifact_checks( |
| [ |
| { |
| "phase": "fault_quick_p1", |
| "status": "passed", |
| "started_at": 1.0, |
| "finished_at": 2.0, |
| } |
| ], |
| expected_phase_count=4, |
| ) |
| assert checks["all_status_valid"] is True |
| assert checks["all_timestamps_present"] is True |
| assert checks["expected_phase_count"] == 4 |
|
|
|
|
| def test_check_quality_trends_builds_delta_checks(): |
| project_root = Path(__file__).resolve().parents[1] |
| module = _load_script_module("check_quality_trends_script", project_root / "scripts" / "check_quality_trends.py") |
|
|
| soak = { |
| "failed_count": 0, |
| "results": [ |
| {"phase": "sim_baseline", "duration_sec": 8.0}, |
| {"phase": "retry_and_circuit", "duration_sec": 2.0}, |
| ], |
| } |
| fault = { |
| "failed_count": 0, |
| "results": [ |
| {"phase": "fault_quick", "duration_sec": 1.5}, |
| ], |
| } |
| metrics = module._metric_snapshot(soak, fault) |
| assert metrics["soak_failed_count"] == 0.0 |
| assert metrics["soak_sim_baseline_duration_sec"] == 8.0 |
| assert metrics["fault_quick_duration_sec"] == 1.5 |
|
|
| checks = module._build_checks( |
| metrics=metrics, |
| baseline={ |
| "soak": { |
| "max_failed_count": 0, |
| "baseline_avg_phase_duration_sec": 3.0, |
| "max_avg_phase_duration_delta_sec": 2.0, |
| "baseline_sim_baseline_duration_sec": 7.0, |
| "max_sim_baseline_duration_delta_sec": 2.0, |
| }, |
| "fault": { |
| "max_failed_count": 0, |
| "baseline_avg_phase_duration_sec": 1.0, |
| "max_avg_phase_duration_delta_sec": 1.0, |
| "baseline_quick_duration_sec": 1.0, |
| "max_quick_duration_delta_sec": 1.0, |
| }, |
| }, |
| ) |
| assert len(checks) == 6 |
| assert all("name" in check for check in checks) |
| assert all("passed" in check for check in checks) |
|
|
|
|
| def test_assistant_contract_dataset_has_adversarial_coverage(): |
| project_root = Path(__file__).resolve().parents[1] |
| dataset_path = project_root / "docs" / "evals" / "assistant-contract.json" |
| payload = json.loads(dataset_path.read_text(encoding="utf-8")) |
| cases = payload.get("cases") |
| assert isinstance(cases, list) |
| assert len(cases) >= 250 |
|
|
| case_ids = {str(case.get("id", "")) for case in cases if isinstance(case, dict)} |
| required_ids = { |
| "adv_prompt_injection_policy_override", |
| "adv_identity_spoof_requester_mismatch", |
| "adv_checkpoint_bypass_requires_token", |
| "adv_circuit_breaker_short_circuit", |
| "adv_plan_preview_token_ttl_enforced", |
| "sim_voice_edge_001", |
| "sim_autonomy_edge_001", |
| } |
| assert required_ids.issubset(case_ids) |
|
|
|
|
| def test_router_policy_dataset_has_adversarial_coverage(): |
| project_root = Path(__file__).resolve().parents[1] |
| dataset_path = project_root / "docs" / "evals" / "router-policy-contract.json" |
| payload = json.loads(dataset_path.read_text(encoding="utf-8")) |
| cases = payload.get("cases") |
| assert isinstance(cases, list) |
| assert len(cases) >= 20 |
|
|
| case_ids = {str(case.get("id", "")) for case in cases if isinstance(case, dict)} |
| required_ids = { |
| "adv_router_prompt_injection_fail_closed", |
| "adv_router_identity_spoof_fail_closed", |
| "adv_router_tool_escalation_requires_confirmation", |
| "adv_router_ambiguous_unlock_requires_safety", |
| "router_fallback_default_contract", |
| } |
| assert required_ids.issubset(case_ids) |
|
|
|
|
| def test_interruption_route_dataset_has_adversarial_coverage(): |
| project_root = Path(__file__).resolve().parents[1] |
| dataset_path = project_root / "docs" / "evals" / "interruption-route-contract.json" |
| payload = json.loads(dataset_path.read_text(encoding="utf-8")) |
| cases = payload.get("cases") |
| assert isinstance(cases, list) |
| assert len(cases) >= 20 |
|
|
| case_ids = {str(case.get("id", "")) for case in cases if isinstance(case, dict)} |
| required_ids = { |
| "adv_interruption_prompt_injection_forced_replace", |
| "adv_interruption_identity_spoof_forced_replace", |
| "adv_interruption_low_confidence_resume_forced_replace", |
| "adv_interruption_correction_never_resume", |
| "router_fallback_default_contract", |
| } |
| assert required_ids.issubset(case_ids) |
|
|
|
|
| def test_trajectory_trace_dataset_has_adversarial_coverage(): |
| project_root = Path(__file__).resolve().parents[1] |
| dataset_path = project_root / "docs" / "evals" / "trajectory-trace-contract.json" |
| payload = json.loads(dataset_path.read_text(encoding="utf-8")) |
| cases = payload.get("cases") |
| assert isinstance(cases, list) |
| assert len(cases) >= 10 |
|
|
| case_ids = {str(case.get("id", "")) for case in cases if isinstance(case, dict)} |
| required_ids = { |
| "adv_trace_prompt_injection_guardrail_retained", |
| "adv_trace_identity_spoof_guardrail_retained", |
| "adv_trace_interruption_recovery_quality", |
| "adv_trace_linkage_integrity_preserved", |
| "router_fallback_default_contract", |
| } |
| assert required_ids.issubset(case_ids) |
|
|
|
|
| def test_autonomy_cycle_dataset_has_adversarial_coverage(): |
| project_root = Path(__file__).resolve().parents[1] |
| dataset_path = project_root / "docs" / "evals" / "autonomy-cycle-contract.json" |
| payload = json.loads(dataset_path.read_text(encoding="utf-8")) |
| cases = payload.get("cases") |
| assert isinstance(cases, list) |
| assert len(cases) >= 10 |
|
|
| case_ids = {str(case.get("id", "")) for case in cases if isinstance(case, dict)} |
| required_ids = { |
| "adv_autonomy_precondition_retry_escalates_replan", |
| "adv_autonomy_postcondition_retry_recovers", |
| "adv_autonomy_checkpoint_gate_blocks_until_approved", |
| "adv_autonomy_failure_taxonomy_accumulates", |
| "autonomy_default_contract", |
| } |
| assert required_ids.issubset(case_ids) |
|
|