$ErrorActionPreference = "Stop" $script:config = [pscustomobject]@{ api3_account = "operator"; api3_password = "secret"; api3_port = 4433 } $script:calls = @() $script:outcomes = @() $script:outcomeIndex = 0 function Read-AgentConfig { return $script:config } . (Join-Path (Split-Path $PSScriptRoot -Parent) "MinerOpsControl.ps1") function Invoke-MinerOpsControlApi3Command { param([string]$IpAddress, [string]$Command, [object]$Param = $null) $script:calls += [pscustomobject]@{ command = $Command; param = $Param } $outcome = $script:outcomes[$script:outcomeIndex] $script:outcomeIndex += 1 if ($outcome -is [System.Exception]) { throw $outcome } return $outcome } function Assert-Equal($Actual, $Expected, [string]$Message) { if ($Actual -ne $Expected) { throw "$Message. Expected '$Expected', got '$Actual'." } } function Reset-Harness([object[]]$Outcomes) { $script:calls = @() $script:outcomes = @($Outcomes) $script:outcomeIndex = 0 } function Response([string]$Mode = "") { return @{ response = @{ code = 0; msg = @{ "power-mode" = $Mode } } } } $payload = @{ action = "performance_mode"; requested_value = "normal"; ip_address = "192.0.2.1" } $script:config = [pscustomobject]@{ api3_account = ""; api3_password = ""; api3_port = 4433 } Reset-Harness @() $result = Run-MinerControlCommand -Payload $payload Assert-Equal $result.failure_code "credentials_missing" "Missing credentials code" Assert-Equal $script:calls.Count 0 "Missing credentials must not contact API3" $script:config = [pscustomobject]@{ api3_account = "operator"; api3_password = "secret"; api3_port = 4433 } Reset-Harness @((Response), (Response "normal")) $result = Run-MinerControlCommand -Payload $payload Assert-Equal $result.verification_status "confirmed" "Performance confirmation" Assert-Equal @($script:calls | Where-Object command -Like "set.*").Count 1 "Exactly one write" Reset-Harness @((Response), (Response "low"), (Response "low"), (Response "low")) $result = Run-MinerControlCommand -Payload $payload Assert-Equal $result.verification_status "verification_failed" "Contradictory mode" Assert-Equal $script:calls.Count 4 "One write and three bounded reads" Reset-Harness @((Response), (Response), (Response), (Response)) $result = Run-MinerControlCommand -Payload $payload Assert-Equal $result.verification_status "unconfirmed" "Ambiguous reads" Reset-Harness @((Response), [System.Exception]::new("unknown_command")) $result = Run-MinerControlCommand -Payload $payload Assert-Equal $result.verification_status "unavailable" "Unavailable read path" foreach ($action in @("suspend", "resume")) { Reset-Harness @((Response)) $result = Run-MinerControlCommand -Payload @{ action = $action; requested_value = $null; ip_address = "192.0.2.1" } Assert-Equal $result.command_accepted $true "$action accepted" Assert-Equal $result.verification_status "unconfirmed" "$action remains unconfirmed" Assert-Equal $result.observed_service_state $null "$action has no invented state" Assert-Equal @($script:calls | Where-Object command -Like "set.*").Count 1 "$action one write" } Reset-Harness @([System.Exception]::new("vendor response included secret")) $result = Run-MinerControlCommand -Payload @{ action = "suspend"; requested_value = $null; ip_address = "192.0.2.1" } Assert-Equal $result.failure_code "write_rejected" "Write rejection is sanitized" $json = $result | ConvertTo-Json -Compress if ($json -match "vendor|secret|192\\.0\\.2\\.1") { throw "Typed result leaked raw data" } Reset-Harness @() $result = Run-MinerControlCommand -Payload @{ action = "performance_mode"; requested_value = "turbo"; ip_address = "192.0.2.1" } Assert-Equal $result.failure_code "invalid_mode" "Invalid mode code" Assert-Equal $script:calls.Count 0 "Invalid mode must not contact API3" Write-Host "MinerOps typed Agent control tests passed."