[CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$BaseUrl ) $ErrorActionPreference = 'Stop' Set-StrictMode -Version 2.0 $script:Failures = 0 function Report-Result { param( [Parameter(Mandatory = $true)][bool]$Passed, [Parameter(Mandatory = $true)][string]$Name, [string]$Detail ) if ($Passed) { if ($Detail) { Write-Output "PASS: $Name ($Detail)" } else { Write-Output "PASS: $Name" } } else { if ($Detail) { Write-Output "FAIL: $Name ($Detail)" } else { Write-Output "FAIL: $Name" } $script:Failures++ } } function Invoke-HttpRequest { param([Parameter(Mandatory = $true)][string]$Uri) $request = [System.Net.HttpWebRequest]::Create($Uri) $request.Method = 'GET' $request.AllowAutoRedirect = $false $response = $null try { try { $response = $request.GetResponse() } catch [System.Net.WebException] { if ($_.Exception.Response) { $response = $_.Exception.Response } else { throw } } $reader = New-Object System.IO.StreamReader($response.GetResponseStream()) try { $body = $reader.ReadToEnd() } finally { $reader.Dispose() } return [PSCustomObject]@{ StatusCode = [int]$response.StatusCode ContentType = [string]$response.ContentType Body = $body } } finally { if ($response) { $response.Dispose() } } } function Read-SelfTestJson { param( [Parameter(Mandatory = $true)][string]$Uri, [Parameter(Mandatory = $true)][string]$Label, [switch]$PrintChecks ) try { $response = Invoke-HttpRequest -Uri $Uri Report-Result ($response.StatusCode -eq 200) "$Label HTTP status 200" "got $($response.StatusCode)" if ($response.StatusCode -ne 200) { return } try { $document = $response.Body | ConvertFrom-Json } catch { Report-Result $false "$Label JSON parses" $_.Exception.Message return } Report-Result $true "$Label JSON parses" $null if (-not $document.PSObject.Properties['ok'] -or -not $document.PSObject.Properties['checks']) { Report-Result $false "$Label JSON contract" "expected 'ok' and 'checks'" return } Report-Result $true "$Label JSON contract" $null if ($PrintChecks) { foreach ($check in @($document.checks)) { $name = [string]$check.name if (-not $name) { $name = '' } $detail = [string]$check.detail Report-Result ([bool]$check.pass) $name $detail } } Report-Result ([bool]$document.ok) "$Label reports overall pass" $null } catch { Report-Result $false "$Label request" $_.Exception.Message } } $normalizedBaseUrl = $BaseUrl.TrimEnd('/') Read-SelfTestJson -Uri "$normalizedBaseUrl/self-test" -Label 'GET /self-test' -PrintChecks Read-SelfTestJson -Uri "$normalizedBaseUrl/" -Label 'GET / (test root)' try { $directHello = Invoke-HttpRequest -Uri "$normalizedBaseUrl/Default.asp?route=/hello" Report-Result ($directHello.StatusCode -eq 404) 'Direct Default.asp production route is rejected' "got HTTP $($directHello.StatusCode)" } catch { Report-Result $false 'Direct Default.asp production route is rejected' $_.Exception.Message } Write-Output '---' if ($script:Failures -eq 0) { Write-Output 'RESULT: ALL PASS' exit 0 } Write-Output "RESULT: $($script:Failures) FAILURE(S)" exit 1