fix(reboot): add windows99 vmx backup search package
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m14s
CD Pipeline / build-and-deploy (push) Successful in 4m45s
CD Pipeline / post-deploy-checks (push) Successful in 1m57s

This commit is contained in:
Your Name
2026-07-03 18:06:34 +08:00
parent b0dc42aa6f
commit 796b66c967
14 changed files with 1260 additions and 56 deletions

View File

@@ -812,7 +812,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
is False
)
assert state["windows99_vmx_source_locator_status"] == (
"collector_readback_verified_source_required_before_relink_dry_run"
"collector_readback_no_scoped_relink_candidate"
)
assert state["windows99_vmx_source_locator_required"] is True
assert state["windows99_vmx_source_locator_check_mode_ready"] is True
@@ -826,19 +826,19 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
)
assert state["windows99_vmx_source_locator_target_aliases"] == ["111"]
assert state["windows99_vmx_source_locator_next_executable_step"] == (
"provide_verified_vmx_source_or_identity_evidence_then_scoped_relink_dry_run"
"provide_existing_vmx_source_or_backup_path"
)
assert state["windows99_vmx_source_locator_expected_vmx_path_count"] == 1
assert state["windows99_vmx_source_locator_candidate_source_count"] == 6
assert state["windows99_vmx_source_locator_candidate_source_count"] == 0
assert state["windows99_vmx_source_locator_alias_hint_candidate_count"] == 0
assert state["windows99_vmx_source_locator_unassigned_ubuntu_candidate_count"] == 5
assert state["windows99_vmx_source_locator_unassigned_ubuntu_candidate_count"] == 0
assert (
state[
"windows99_vmx_source_locator_identity_unassigned_ubuntu_candidate_count"
]
== 1
== 0
)
assert state["windows99_vmx_source_locator_candidate_confirmation_required"] is True
assert state["windows99_vmx_source_locator_candidate_confirmation_required"] is False
assert (
state[
"windows99_vmx_source_locator_human_confirmation_required_for_dry_run"
@@ -849,7 +849,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
state[
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
]
is True
is False
)
assert (
state["windows99_vmx_source_locator_controlled_relink_dry_run_ready"]
@@ -857,12 +857,12 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
)
assert state[
"windows99_vmx_source_locator_controlled_relink_dry_run_blocker"
] == "verified_vmx_source_or_identity_evidence_missing"
] == "scoped_relink_candidate_not_verified"
assert state["windows99_vmx_source_locator_relink_dry_run_plan_id"] == (
"windows99-vmx-source-relink-dry-run-111"
)
assert state["windows99_vmx_source_locator_candidate_confirmation_status"] == (
"blocked_single_unassigned_ubuntu_candidate_identity_not_confirmed"
"blocked_no_candidate_source_found"
)
assert state["windows99_vmx_source_locator_candidate_identity_decision"] == (
"blocked"
@@ -876,12 +876,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
assert state["windows99_vmx_source_locator_candidate_relink_dry_run_ready"] is False
assert state[
"windows99_vmx_source_locator_candidate_confirmation_missing_evidence"
] == [
"target_alias_identity_hint",
"verified_backup_or_authorized_console_candidate_identity",
"pre_apply_backup_plan",
"scoped_relink_dry_run",
]
] == ["existing_vmx_source_or_verified_backup_path"]
assert (
state[
"windows99_vmx_source_locator_apply_allowed_by_candidate_confirmation_gate"
@@ -890,9 +885,36 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
)
assert state["windows99_vmx_source_locator_candidate_source_count_known"] is True
assert state["windows99_vmx_source_locator_collector_readback_present"] is True
assert state["windows99_vmx_source_locator_file_content_read"] is True
assert state["windows99_vmx_source_locator_file_content_read"] is False
assert state["windows99_vmx_source_locator_remote_write_performed"] is False
assert state["windows99_vmx_source_locator_vm_power_change_performed"] is False
assert state["windows99_vmx_source_backup_search_package_status"] == (
"blocked_windows99_vmx_backup_source_not_found_some_hosts_unsearched"
)
assert state["windows99_vmx_source_backup_search_package_ready"] is True
assert state["windows99_vmx_source_backup_search_target_aliases"] == ["111"]
assert state["windows99_vmx_source_backup_search_receipt_readback_present"] is True
assert state["windows99_vmx_source_backup_search_host_count"] == 7
assert state["windows99_vmx_source_backup_search_searched_host_count"] == 4
assert state["windows99_vmx_source_backup_search_blocked_host_count"] == 3
assert state["windows99_vmx_source_backup_search_blocked_host_aliases"] == [
"110",
"188",
"112",
]
assert state["windows99_vmx_source_backup_search_candidate_source_count"] == 0
assert state["windows99_vmx_source_backup_search_candidate_source_found"] is False
assert (
state["windows99_vmx_source_backup_search_apply_allowed_by_this_package"]
is False
)
assert state["windows99_vmx_source_backup_search_raw_path_output"] is False
assert state["windows99_vmx_source_backup_search_path_fingerprint_only"] is True
assert state["windows99_vmx_source_backup_search_file_content_read"] is False
assert state["windows99_vmx_source_backup_search_remote_write_performed"] is False
assert (
state["windows99_vmx_source_backup_search_vm_power_change_performed"] is False
)
assert payload["summary"]["controlled_service_data_backup_blocker_count"] == 0
assert payload["summary"]["active_p0_primary_blocker"] == (
"reboot_event_required_host_unreachable"
@@ -992,28 +1014,28 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
"111"
]
assert payload["summary"]["windows99_vmx_source_locator_status"] == (
"collector_readback_verified_source_required_before_relink_dry_run"
"collector_readback_no_scoped_relink_candidate"
)
assert payload["summary"]["windows99_vmx_source_locator_check_mode_ready"] is True
assert payload["summary"]["windows99_vmx_source_locator_target_aliases"] == [
"111"
]
assert payload["summary"]["windows99_vmx_source_locator_candidate_source_count"] == 6
assert payload["summary"]["windows99_vmx_source_locator_candidate_source_count"] == 0
assert (
payload["summary"][
"windows99_vmx_source_locator_identity_unassigned_ubuntu_candidate_count"
]
== 1
== 0
)
assert (
payload["summary"][
"windows99_vmx_source_locator_candidate_confirmation_required"
]
is True
is False
)
assert payload["summary"][
"windows99_vmx_source_locator_candidate_confirmation_status"
] == "blocked_single_unassigned_ubuntu_candidate_identity_not_confirmed"
] == "blocked_no_candidate_source_found"
assert payload["summary"][
"windows99_vmx_source_locator_candidate_identity_decision"
] == "blocked"
@@ -1045,7 +1067,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
payload["summary"][
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
]
is True
is False
)
assert (
payload["rollups"][
@@ -1055,15 +1077,20 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
)
assert payload["rollups"][
"windows99_vmx_source_locator_controlled_relink_dry_run_blocker"
] == "verified_vmx_source_or_identity_evidence_missing"
] == "scoped_relink_candidate_not_verified"
assert (
payload["rollups"]["windows99_vmx_source_locator_remote_write_performed"]
is False
)
assert (
payload["rollups"]["windows99_vmx_source_locator_file_content_read"]
is True
is False
)
assert payload["summary"]["windows99_vmx_source_backup_search_status"] == (
"blocked_windows99_vmx_backup_source_not_found_some_hosts_unsearched"
)
assert payload["summary"]["windows99_vmx_source_backup_search_candidate_source_count"] == 0
assert payload["rollups"]["windows99_vmx_source_backup_search_blocked_host_count"] == 3
assert "service/data/backup readback is green" in payload[
"next_execution_order"
][0]
@@ -1114,7 +1141,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
"windows99_vmx_source_repair_playbook_trust_writeback_ref"
].startswith("playbook://awoooi/windows99-vmx-source-repair/")
assert in_progress["evidence"]["windows99_vmx_source_locator_status"] == (
"collector_readback_verified_source_required_before_relink_dry_run"
"collector_readback_no_scoped_relink_candidate"
)
assert (
in_progress["evidence"]["windows99_vmx_source_locator_check_mode_ready"]
@@ -1126,17 +1153,17 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
)
assert (
in_progress["evidence"]["windows99_vmx_source_locator_candidate_source_count"]
== 6
== 0
)
assert (
in_progress["evidence"][
"windows99_vmx_source_locator_candidate_confirmation_required"
]
is True
is False
)
assert in_progress["evidence"][
"windows99_vmx_source_locator_candidate_confirmation_status"
] == "blocked_single_unassigned_ubuntu_candidate_identity_not_confirmed"
] == "blocked_no_candidate_source_found"
assert (
in_progress["evidence"][
"windows99_vmx_source_locator_candidate_relink_dry_run_ready"
@@ -1159,7 +1186,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
in_progress["evidence"][
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
]
is True
is False
)
assert (
in_progress["evidence"][
@@ -1171,6 +1198,20 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
in_progress["evidence"]["windows99_vmx_source_locator_remote_write_performed"]
is False
)
assert in_progress["evidence"]["windows99_vmx_source_backup_search_package_status"] == (
"blocked_windows99_vmx_backup_source_not_found_some_hosts_unsearched"
)
assert (
in_progress["evidence"]["windows99_vmx_source_backup_search_candidate_source_count"]
== 0
)
assert in_progress["evidence"]["windows99_vmx_source_backup_search_blocked_host_count"] == 3
assert (
in_progress["evidence"][
"windows99_vmx_source_backup_search_apply_allowed_by_this_package"
]
is False
)
assert "Windows99 verify collection" in in_progress["professional_fix"][
"action"
]

View File

@@ -0,0 +1,195 @@
from __future__ import annotations
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from src.api.v1 import agents
from src.api.v1.agents import router
from src.services.windows99_vmx_source_backup_search_package import (
build_windows99_vmx_source_backup_search_package,
)
from src.services.windows99_vmx_source_locator_readback import (
build_windows99_vmx_source_locator_readback,
)
from src.services.windows99_vmx_source_repair_package import (
build_windows99_vmx_source_repair_package,
)
def _scorecard() -> dict:
return {
"status": "blocked_reboot_auto_recovery_slo_not_ready",
"generated_at": "2026-07-03T17:57:16+08:00",
"windows99_vmware_autostart": {
"required_vm_aliases": ["111", "188", "120", "121", "112"],
"missing_vmx_aliases": ["111"],
"powered_off_aliases": ["111", "112", "120", "121", "188"],
},
"readback": {
"windows99_no_secret_collector_status": (
"collected_windows99_vmware_verify_stdout"
),
"windows99_no_secret_collector_readback_present": True,
"windows99_no_secret_collector_ssh_batchmode_auth_ready": True,
"windows99_no_secret_collector_remote_verify_attempted": True,
},
"windows99_management_channel": {
"remote_execution_channel_ready": False,
"can_collect_vmware_verify_without_secret": False,
"winrm_http_open": False,
"winrm_https_open": False,
"local_console_channel_reachable": True,
"console_collection_channels": ["rdp_console", "hyperv_vmconnect"],
"ssh_batch": {
"checked": True,
"ready": False,
"status": "permission_denied",
},
},
}
def _locator_readback() -> dict:
repair_package = build_windows99_vmx_source_repair_package(_scorecard())
return build_windows99_vmx_source_locator_readback(
_scorecard(),
repair_package=repair_package,
collector_receipt={
"schema_version": "windows99_vmx_source_locator_receipt_v1",
"collector_readback_present": True,
"collector_collection_status": (
"collected_windows99_vmx_source_locator_stdout"
),
"target_host_alias": "99",
"target_vm_aliases": ["111"],
"expected_vmx_path_present_count": 0,
"candidate_source_count": 0,
"candidate_source_fingerprint_count": 0,
"alias_hint_candidate_count": 0,
"unassigned_ubuntu_candidate_count": 0,
"identity_metadata_read": False,
"bounded_identity_metadata_only": False,
"identity_target_hint_count": 0,
"identity_unassigned_ubuntu_candidate_count": 0,
"locate_status": "blocked_missing_expected_vmx_source_no_candidate_found",
},
)
def _backup_search_receipt() -> dict:
return {
"schema_version": "windows99_vmx_source_backup_search_receipt_v1",
"collector_readback_present": True,
"target_host_alias": "99",
"target_vm_aliases": ["111"],
"host_rows": [
{
"host_alias": "99",
"status": "not_matched",
"candidate_source_count": 0,
"candidate_source_count_known": True,
"candidate_source_fingerprint_count": 0,
},
{
"host_alias": "120",
"status": "searched",
"candidate_source_count": 0,
"candidate_source_count_known": True,
"candidate_source_fingerprint_count": 0,
},
{
"host_alias": "121",
"status": "searched",
"candidate_source_count": 0,
"candidate_source_count_known": True,
"candidate_source_fingerprint_count": 0,
},
{
"host_alias": "188",
"status": "blocked_ssh_batchmode_unavailable",
"candidate_source_count": 0,
"candidate_source_count_known": False,
"candidate_source_fingerprint_count": 0,
},
],
}
def test_windows99_vmx_source_backup_search_package_builder_is_check_mode_only() -> None:
payload = build_windows99_vmx_source_backup_search_package(
_scorecard(),
locator_readback=_locator_readback(),
collector_receipt=_backup_search_receipt(),
generated_at="2026-07-03T17:58:00+08:00",
)
assert payload["schema_version"] == "windows99_vmx_source_backup_search_package_v1"
assert payload["status"] == (
"blocked_windows99_vmx_backup_source_not_found_some_hosts_unsearched"
)
assert payload["package_ready"] is True
assert payload["target_vm_aliases"] == ["111"]
assert payload["source_locator_candidate_source_count"] == 0
assert payload["receipt_readback_present"] is True
assert payload["search_host_count"] == 4
assert payload["searched_host_count"] == 3
assert payload["blocked_host_count"] == 1
assert payload["blocked_host_aliases"] == ["188"]
assert payload["candidate_source_count"] == 0
assert payload["candidate_source_found"] is False
assert payload["next_executable_step"] == (
"rerun_backup_search_for_blocked_hosts_or_offline_inventory"
)
assert payload["apply_allowed_by_this_package"] is False
assert payload["raw_path_output"] is False
assert payload["path_fingerprint_only"] is True
assert payload["file_content_read"] is False
assert payload["secret_value_read"] is False
assert payload["remote_write_performed"] is False
assert payload["vm_power_change_performed"] is False
assert payload["vm_power_change_allowed"] is False
assert payload["destructive_restore_allowed"] is False
assert "read_vmx_file_contents" in payload["forbidden_actions"]
assert payload["operation_boundaries"]["path_fingerprint_only"] is True
assert payload["post_search_verifier"] == [
"GET /api/v1/agents/windows99-vmx-source-backup-search-package",
"GET /api/v1/agents/windows99-vmx-source-locator-readback",
"GET /api/v1/agents/reboot-auto-recovery-slo-scorecard",
"GET /api/v1/agents/awoooi-priority-work-order-readback",
]
def test_windows99_vmx_source_backup_search_endpoint_is_public_safe(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr(
agents,
"load_latest_windows99_vmx_source_backup_search_package",
lambda: build_windows99_vmx_source_backup_search_package(
_scorecard(),
locator_readback=_locator_readback(),
collector_receipt=_backup_search_receipt(),
),
)
app = FastAPI()
app.include_router(router, prefix="/api/v1")
client = TestClient(app)
response = client.get("/api/v1/agents/windows99-vmx-source-backup-search-package")
assert response.status_code == 200
payload = response.json()
assert payload["schema_version"] == "windows99_vmx_source_backup_search_package_v1"
assert payload["target_vm_aliases"] == ["111"]
assert payload["candidate_source_count"] == 0
assert payload["blocked_host_aliases"] == ["188"]
assert payload["public_lan_topology_redacted"] is True
assert payload["raw_path_output"] is False
assert payload["file_content_read"] is False
assert payload["remote_write_performed"] is False
assert payload["vm_power_change_performed"] is False
assert "192.168.0." not in response.text
assert "D:\\" not in response.text
assert "/Users/" not in response.text
assert "/Volumes/" not in response.text

View File

@@ -219,32 +219,33 @@ def test_windows99_vmx_source_locator_endpoint_returns_public_safe_readback(
payload = response.json()
assert payload["schema_version"] == "windows99_vmx_source_locator_readback_v1"
assert payload["status"] == (
"collector_readback_verified_source_required_before_relink_dry_run"
"collector_readback_no_scoped_relink_candidate"
)
assert payload["target_vm_aliases"] == ["111"]
assert payload["locator_check_mode_ready"] is True
assert payload["effective_locator_collect_ready"] is False
assert payload["locator_collect_blocker"] == "ssh_batch_permission_denied"
assert payload["collector_readback_present"] is True
assert payload["candidate_source_count"] == 6
assert payload["candidate_confirmation_required"] is True
assert payload["candidate_source_count"] == 0
assert payload["candidate_confirmation_required"] is False
assert payload["human_confirmation_required_for_dry_run"] is False
assert payload["verified_source_or_identity_evidence_required"] is True
assert payload["verified_source_or_identity_evidence_required"] is False
assert payload["controlled_relink_dry_run_ready"] is False
assert payload["controlled_relink_dry_run_blocker"] == (
"verified_vmx_source_or_identity_evidence_missing"
"scoped_relink_candidate_not_verified"
)
assert payload["controlled_relink_dry_run_plan"]["plan_id"] == (
"windows99-vmx-source-relink-dry-run-111"
)
assert payload["controlled_relink_dry_run_plan"]["remote_write_performed"] is False
assert payload["candidate_confirmation_status"] == "blocked_no_candidate_source_found"
assert payload["candidate_identity_evidence_sufficient"] is False
assert payload["candidate_relink_dry_run_ready"] is False
assert payload["apply_allowed_by_candidate_confirmation_gate"] is False
assert payload["public_lan_topology_redacted"] is True
assert payload["raw_path_output"] is False
assert payload["file_content_read"] is True
assert payload["bounded_identity_metadata_only"] is True
assert payload["file_content_read"] is False
assert payload["bounded_identity_metadata_only"] is False
assert payload["remote_write_performed"] is False
assert payload["vm_power_change_performed"] is False
assert "192.168.0." not in response.text