aboutsummaryrefslogtreecommitdiffstats
path: root/packaging/win/smoke-node-runtime.ps1
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/win/smoke-node-runtime.ps1')
-rw-r--r--packaging/win/smoke-node-runtime.ps1107
1 files changed, 107 insertions, 0 deletions
diff --git a/packaging/win/smoke-node-runtime.ps1 b/packaging/win/smoke-node-runtime.ps1
new file mode 100644
index 0000000..bfcabac
--- /dev/null
+++ b/packaging/win/smoke-node-runtime.ps1
@@ -0,0 +1,107 @@
+<#
+.SYNOPSIS
+ Start a frozen meshbay-node as a daemon and check it answers as the version
+ it claims to be.
+
+.DESCRIPTION
+ `meshbay-node --help` imports the parser and nothing else, so it passes for
+ a bundle that cannot start the daemon at all. This starts the real daemon,
+ in a throwaway profile (its own LOCALAPPDATA, an unused port, a hub URL
+ nothing listens on -- it never touches a real hub or the developer's own
+ node), waits for its control API, and checks:
+ - /api/status answers, with the expected version;
+ - the Windows log file was written (a service-mode daemon has no console,
+ and this file is the only place its errors go).
+
+ Also useful against an installed build:
+ smoke-node-runtime.ps1 -Exe "$env:LOCALAPPDATA\Programs\MeshBay\resources\node-runtime\meshbay-node.exe" -ExpectVersion 0.16.0
+
+.PARAMETER Exe
+ The meshbay-node.exe to start.
+
+.PARAMETER ExpectVersion
+ The version /api/status must report.
+#>
+[CmdletBinding()]
+param(
+ [Parameter(Mandatory = $true)][string]$Exe,
+ [Parameter(Mandatory = $true)][string]$ExpectVersion,
+ [int]$TimeoutSeconds = 45
+)
+
+$ErrorActionPreference = "Stop"
+Set-StrictMode -Version Latest
+
+$profileDir = Join-Path ([IO.Path]::GetTempPath()) ("meshbay-smoke-" + [guid]::NewGuid().ToString("N"))
+$meshbay = Join-Path $profileDir "meshbay"
+New-Item -ItemType Directory -Force $meshbay | Out-Null
+
+# A free loopback port, so a node already running here on 18000 is untouched.
+$listener = [Net.Sockets.TcpListener]::new([Net.IPAddress]::Loopback, 0)
+$listener.Start()
+$port = $listener.LocalEndpoint.Port
+$listener.Stop()
+
+$bytes = New-Object byte[] 32
+[Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes)
+$unlock = Join-Path $meshbay "unlock.key"
+Set-Content -Encoding ascii -LiteralPath $unlock ([Convert]::ToBase64String($bytes))
+$unlockToml = $unlock.Replace([char]92, [char]47)
+Set-Content -Encoding ascii -LiteralPath (Join-Path $meshbay "node.toml") @"
+[hub]
+url = "http://127.0.0.1:1"
+username = "smoke"
+
+[node]
+quic_enabled = false
+ui_port = $port
+
+[keystore]
+unlock_file = "$unlockToml"
+"@
+
+$oldLocal = $env:LOCALAPPDATA
+$env:LOCALAPPDATA = $profileDir
+$stderr = Join-Path $profileDir "stderr.txt"
+$proc = $null
+try {
+ $proc = Start-Process -FilePath $Exe -PassThru -WindowStyle Hidden `
+ -RedirectStandardError $stderr -RedirectStandardOutput (Join-Path $profileDir "stdout.txt")
+ $env:LOCALAPPDATA = $oldLocal
+
+ $tokenFile = Join-Path $meshbay "data\ui-token"
+ $status = $null
+ $deadline = (Get-Date).AddSeconds($TimeoutSeconds)
+ while ((Get-Date) -lt $deadline -and -not $proc.HasExited) {
+ if (Test-Path -LiteralPath $tokenFile) {
+ try {
+ $token = (Get-Content -LiteralPath $tokenFile -Raw).Trim()
+ $status = Invoke-RestMethod "http://127.0.0.1:$port/api/status?t=$token" -TimeoutSec 3
+ break
+ } catch { }
+ }
+ Start-Sleep -Milliseconds 500
+ }
+
+ $tail = if (Test-Path -LiteralPath $stderr) { (Get-Content -LiteralPath $stderr -Tail 30) -join "`n" } else { "" }
+ if ($proc.HasExited) {
+ throw "the frozen daemon exited (code $($proc.ExitCode)) before its control API answered:`n$tail"
+ }
+ if ($null -eq $status) {
+ throw "the frozen daemon's control API did not answer within ${TimeoutSeconds}s:`n$tail"
+ }
+ if ($status.version -ne $ExpectVersion) {
+ throw "the frozen daemon reports version '$($status.version)', expected '$ExpectVersion'"
+ }
+ $log = Join-Path $meshbay "state\node.log"
+ if (-not (Test-Path -LiteralPath $log) -or (Get-Item -LiteralPath $log).Length -eq 0) {
+ throw "the frozen daemon wrote no log file at $log"
+ }
+ Write-Host "OK daemon answered: version $($status.version), status $($status.status), log $log" -ForegroundColor Green
+}
+finally {
+ $env:LOCALAPPDATA = $oldLocal
+ if ($proc -and -not $proc.HasExited) { Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue }
+ if ($proc) { $proc.WaitForExit(10000) | Out-Null }
+ Remove-Item -LiteralPath $profileDir -Recurse -Force -ErrorAction SilentlyContinue
+}