test(render): add connected package lifecycle gate
This commit is contained in:
parent
1f75ce0505
commit
f92479ac3e
4 changed files with 507 additions and 12 deletions
|
|
@ -10,6 +10,8 @@ public sealed class ConnectedRenderPackGateContractTests
|
|||
{
|
||||
private const string LifecycleScript = "run-connected-world-lifecycle-gate.ps1";
|
||||
private const string SoakScript = "run-connected-r6-soak.ps1";
|
||||
private const string PackageLifecycleScript =
|
||||
"run-connected-render-pack-package-lifecycle.ps1";
|
||||
|
||||
[Fact]
|
||||
public void ScreenshotJsonCarriesAuthoritativeCasterClassCounters()
|
||||
|
|
@ -125,7 +127,8 @@ foreach ($name in $script:ConnectedGateEnvironmentNames) {{
|
|||
}}
|
||||
[Environment]::SetEnvironmentVariable('ACDREAM_FUTURE_GATE_KNOB', 'sentinel-future', 'Process')
|
||||
$state = New-ConnectedRenderPackGateState -Root {rootQuoted} -Preset medium
|
||||
$sessionConfigPath = New-ConnectedGraphicalSessionConfig -State $state -Account 'fixture-account'
|
||||
$statusFile = Join-Path $state.StateDirectory 'status\fixture.jsonl'
|
||||
$sessionConfigPath = New-ConnectedGraphicalSessionConfig -State $state -Account 'fixture-account' -Plugins @('fixture.render') -StatusFile $statusFile
|
||||
$sessionConfig = Get-Content -Raw -LiteralPath $sessionConfigPath | ConvertFrom-Json
|
||||
$isolated=@($state.PreviousEnvironment.Keys | Where-Object {{
|
||||
$_ -notin @('ACDREAM_CONFIG_DIR', 'ACDREAM_DATA_DIR', 'ACDREAM_CACHE_DIR') -and
|
||||
|
|
@ -153,6 +156,8 @@ Remove-ConnectedGraphicalSessionConfig -State $state -Path $sessionConfigPath
|
|||
SessionCharacterIndex=$sessionConfig.sessions[0].character.index;
|
||||
SessionCredentialProvider=$sessionConfig.sessions[0].credential.provider;
|
||||
SessionCredentialReference=$sessionConfig.sessions[0].credential.reference;
|
||||
SessionPlugins=@($sessionConfig.sessions[0].plugins);
|
||||
SessionStatusFile=$sessionConfig.sessions[0].statusFile;
|
||||
Settings=(Get-Content -Raw -LiteralPath (Join-Path $state.ConfigDirectory 'settings.json') | ConvertFrom-Json).display.renderPack.presetId
|
||||
}} | ConvertTo-Json -Compress";
|
||||
using JsonDocument result = JsonDocument.Parse(RunPowerShell(command));
|
||||
|
|
@ -170,6 +175,13 @@ Remove-ConnectedGraphicalSessionConfig -State $state -Path $sessionConfigPath
|
|||
Assert.Equal(0, rootElement.GetProperty("SessionCharacterIndex").GetInt32());
|
||||
Assert.Equal("Environment", rootElement.GetProperty("SessionCredentialProvider").GetString());
|
||||
Assert.Equal("ACDREAM_TEST_PASS", rootElement.GetProperty("SessionCredentialReference").GetString());
|
||||
Assert.Equal(
|
||||
new[] { "fixture.render" },
|
||||
rootElement.GetProperty("SessionPlugins").EnumerateArray()
|
||||
.Select(static value => value.GetString()!).ToArray());
|
||||
Assert.Equal(
|
||||
Path.GetFullPath(Path.Combine(root, "isolated-state", "status", "fixture.jsonl")),
|
||||
rootElement.GetProperty("SessionStatusFile").GetString());
|
||||
Assert.Equal("medium", rootElement.GetProperty("Settings").GetString());
|
||||
}
|
||||
finally { Directory.Delete(root, recursive: true); }
|
||||
|
|
@ -192,6 +204,35 @@ Remove-ConnectedGraphicalSessionConfig -State $state -Path $sessionConfigPath
|
|||
Assert.Contains("reference = $CredentialEnvironmentVariable", common, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConnectedPackageLifecycleRunsSixFreshGraphicalHostScenariosFailClosed()
|
||||
{
|
||||
string source = ReadTool(PackageLifecycleScript);
|
||||
Assert.Contains("Get-ConnectedGateBinaryIdentity", source, StringComparison.Ordinal);
|
||||
Assert.Contains("New-ConnectedRenderPackGateState -Root $root -Preset retail", source, StringComparison.Ordinal);
|
||||
Assert.Contains("-Plugins @($packageId)", source, StringComparison.Ordinal);
|
||||
Assert.Contains("-StatusFile $status", source, StringComparison.Ordinal);
|
||||
Assert.Contains("pluginLoaded", source, StringComparison.Ordinal);
|
||||
Assert.Contains("pluginFailed", source, StringComparison.Ordinal);
|
||||
Assert.Contains("'01-installed-v1-selected'", source, StringComparison.Ordinal);
|
||||
Assert.Contains("'02-updated-v2-stale-selection'", source, StringComparison.Ordinal);
|
||||
Assert.Contains("'03-updated-v2-selected'", source, StringComparison.Ordinal);
|
||||
Assert.Contains("'04-package-removed'", source, StringComparison.Ordinal);
|
||||
Assert.Contains("'05-registration-failed'", source, StringComparison.Ordinal);
|
||||
Assert.Contains("'06-corrected-and-recovered'", source, StringComparison.Ordinal);
|
||||
Assert.Contains("BinaryMatchesSource", source, StringComparison.Ordinal);
|
||||
Assert.Contains("TrackedSourceStatus", source, StringComparison.Ordinal);
|
||||
Assert.Contains("Restore-ConnectedRenderPackGateEnvironment", source, StringComparison.Ordinal);
|
||||
|
||||
string route = ReadTool("connected-render-pack-package-lifecycle.route.txt");
|
||||
AssertAppearsInOrder(
|
||||
route,
|
||||
"wait world-ready 90000",
|
||||
"wait world-visible 30000",
|
||||
"screenshot package-lifecycle 15000",
|
||||
"checkpoint package-lifecycle");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EveryConnectedScreenshotMustProveExactFailureFreeActivation()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -168,7 +168,9 @@ function New-ConnectedGraphicalSessionConfig {
|
|||
[string]$HostName = '127.0.0.1',
|
||||
[ValidateRange(1, 65535)][int]$Port = 9000,
|
||||
[ValidateRange(0, [int]::MaxValue)][int]$CharacterIndex = 0,
|
||||
[string]$CredentialEnvironmentVariable = 'ACDREAM_TEST_PASS'
|
||||
[string]$CredentialEnvironmentVariable = 'ACDREAM_TEST_PASS',
|
||||
[string[]]$Plugins = @(),
|
||||
[string]$StatusFile
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($Account)) {
|
||||
|
|
@ -187,18 +189,36 @@ function New-ConnectedGraphicalSessionConfig {
|
|||
throw "Connected graphical session config already exists: '$path'."
|
||||
}
|
||||
|
||||
$session = [ordered]@{
|
||||
id = 'connected-gate'
|
||||
endpoint = [ordered]@{ host = $HostName; port = $Port }
|
||||
account = $Account
|
||||
character = [ordered]@{ index = $CharacterIndex }
|
||||
credential = [ordered]@{
|
||||
provider = 'Environment'
|
||||
reference = $CredentialEnvironmentVariable
|
||||
}
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('Plugins')) {
|
||||
$orderedPlugins = @($Plugins | ForEach-Object {
|
||||
if ([string]::IsNullOrWhiteSpace($_)) {
|
||||
throw 'Connected graphical session plugin IDs cannot be empty.'
|
||||
}
|
||||
$_
|
||||
} | Sort-Object -Unique)
|
||||
$session['plugins'] = $orderedPlugins
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('StatusFile')) {
|
||||
if ([string]::IsNullOrWhiteSpace($StatusFile)) {
|
||||
throw 'Connected graphical session status file cannot be empty.'
|
||||
}
|
||||
$session['statusFile'] = Assert-ConnectedGateContainedPath `
|
||||
$State.StateDirectory $StatusFile
|
||||
}
|
||||
|
||||
[ordered]@{
|
||||
version = 1
|
||||
sessions = @([ordered]@{
|
||||
id = 'connected-gate'
|
||||
endpoint = [ordered]@{ host = $HostName; port = $Port }
|
||||
account = $Account
|
||||
character = [ordered]@{ index = $CharacterIndex }
|
||||
credential = [ordered]@{
|
||||
provider = 'Environment'
|
||||
reference = $CredentialEnvironmentVariable
|
||||
}
|
||||
})
|
||||
sessions = @($session)
|
||||
} | ConvertTo-Json -Depth 8 |
|
||||
Set-Content -LiteralPath $path -Encoding utf8
|
||||
return $path
|
||||
|
|
|
|||
10
tools/connected-render-pack-package-lifecycle.route.txt
Normal file
10
tools/connected-render-pack-package-lifecycle.route.txt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# One short, repeatable connected graphical-host observation. The package
|
||||
# lifecycle driver reuses this route across fresh processes while it mutates
|
||||
# only its disposable plugin directory and persisted render-pack selection.
|
||||
|
||||
wait world-ready 90000
|
||||
wait world-visible 30000
|
||||
sleep 3000
|
||||
screenshot package-lifecycle 15000
|
||||
checkpoint package-lifecycle
|
||||
sleep 1000
|
||||
424
tools/run-connected-render-pack-package-lifecycle.ps1
Normal file
424
tools/run-connected-render-pack-package-lifecycle.ps1
Normal file
|
|
@ -0,0 +1,424 @@
|
|||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$Repository = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path,
|
||||
[string]$Account = $env:ACDREAM_TEST_USER,
|
||||
[string]$Password = $env:ACDREAM_TEST_PASS,
|
||||
[switch]$SkipBuild,
|
||||
[int]$LoginTimeoutSeconds = 90
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
. (Join-Path $PSScriptRoot 'connected-render-pack-gate-common.ps1')
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($Account)) { $Account = 'testaccount' }
|
||||
if ([string]::IsNullOrWhiteSpace($Password)) { $Password = 'testpassword' }
|
||||
|
||||
$packageId = 'acdream.test.external-render-pack-package'
|
||||
$packId = 'acdream.test.external-render-pack'
|
||||
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
|
||||
$root = Join-Path $Repository `
|
||||
"artifacts\atmospheric-rendering\connected-package-lifecycle-$stamp"
|
||||
$route = Join-Path $Repository `
|
||||
'tools\connected-render-pack-package-lifecycle.route.txt'
|
||||
$exe = Join-Path $Repository `
|
||||
'src\AcDream.App\bin\Release\net10.0\AcDream.App.exe'
|
||||
$fixture = Join-Path $Repository `
|
||||
'tests\AcDream.Plugin.Tests.Fixtures.HostPlugin\bin\Release\net10.0\AcDream.Plugin.Tests.Fixtures.HostPlugin.dll'
|
||||
$startedUtc = [DateTime]::UtcNow.ToString('O')
|
||||
$results = [Collections.Generic.List[object]]::new()
|
||||
$renderPackGate = $null
|
||||
$sessionConfigPath = $null
|
||||
$failure = $null
|
||||
$binaryIdentity = $null
|
||||
|
||||
function Wait-ForLogPattern {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][Diagnostics.Process]$Client,
|
||||
[Parameter(Mandatory = $true)][string]$Path,
|
||||
[Parameter(Mandatory = $true)][string]$Pattern,
|
||||
[Parameter(Mandatory = $true)][int]$TimeoutSeconds
|
||||
)
|
||||
$deadline = [DateTime]::UtcNow.AddSeconds($TimeoutSeconds)
|
||||
while ([DateTime]::UtcNow -lt $deadline) {
|
||||
$Client.Refresh()
|
||||
if ($Client.HasExited) {
|
||||
throw "client exited with code $($Client.ExitCode) while waiting for '$Pattern'"
|
||||
}
|
||||
if (Test-Path -LiteralPath $Path) {
|
||||
if (Select-String -LiteralPath $Path -SimpleMatch $Pattern -Quiet) {
|
||||
return
|
||||
}
|
||||
}
|
||||
Start-Sleep -Milliseconds 250
|
||||
}
|
||||
throw "timed out after $TimeoutSeconds seconds waiting for '$Pattern'"
|
||||
}
|
||||
|
||||
function Close-ClientGracefully {
|
||||
param([Parameter(Mandatory = $true)][Diagnostics.Process]$Client)
|
||||
$Client.Refresh()
|
||||
if ($Client.HasExited) { return }
|
||||
if (-not $Client.CloseMainWindow() -or -not $Client.WaitForExit(30000)) {
|
||||
throw "client $($Client.Id) did not accept graceful close within 30 seconds"
|
||||
}
|
||||
$Client.WaitForExit()
|
||||
}
|
||||
|
||||
function Write-Selection {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Version,
|
||||
[Parameter(Mandatory = $true)][string]$Preset
|
||||
)
|
||||
[ordered]@{
|
||||
display = [ordered]@{
|
||||
renderPack = [ordered]@{
|
||||
packId = $packId
|
||||
packVersion = $Version
|
||||
presetId = $Preset
|
||||
settingOverrides = [ordered]@{}
|
||||
}
|
||||
}
|
||||
version = 3
|
||||
} | ConvertTo-Json -Depth 8 |
|
||||
Set-Content -Encoding utf8 -LiteralPath (
|
||||
Join-Path $renderPackGate.ConfigDirectory 'settings.json')
|
||||
}
|
||||
|
||||
function Write-PackageVersion {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Directory,
|
||||
[Parameter(Mandatory = $true)][string]$Version
|
||||
)
|
||||
Set-Content -Encoding utf8 -NoNewline -LiteralPath (
|
||||
Join-Path $Directory 'render-pack-version.txt') -Value $Version
|
||||
[ordered]@{
|
||||
id = $packageId
|
||||
displayName = 'Connected external render-pack lifecycle fixture'
|
||||
version = $Version
|
||||
entryDll = [IO.Path]::GetFileName($fixture)
|
||||
apiVersion = 1
|
||||
kinds = @('renderPack')
|
||||
} | ConvertTo-Json -Depth 4 |
|
||||
Set-Content -Encoding utf8 -LiteralPath (Join-Path $Directory 'plugin.json')
|
||||
}
|
||||
|
||||
function Install-Package {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Directory,
|
||||
[Parameter(Mandatory = $true)][string]$Version
|
||||
)
|
||||
$null = New-Item -ItemType Directory -Path $Directory
|
||||
Assert-ConnectedGateNoReparsePoint $Directory
|
||||
Copy-Item -LiteralPath $fixture -Destination (
|
||||
Join-Path $Directory ([IO.Path]::GetFileName($fixture)))
|
||||
Write-PackageVersion -Directory $Directory -Version $Version
|
||||
}
|
||||
|
||||
function Read-StatusEvents {
|
||||
param([Parameter(Mandatory = $true)][string]$Path)
|
||||
if (-not (Test-Path -LiteralPath $Path)) {
|
||||
throw "session status stream is missing: '$Path'"
|
||||
}
|
||||
return @(Get-Content -LiteralPath $Path | ForEach-Object {
|
||||
$_ | ConvertFrom-Json
|
||||
})
|
||||
}
|
||||
|
||||
function Assert-SingleStatusEvent {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][object[]]$Events,
|
||||
[Parameter(Mandatory = $true)][string]$Name,
|
||||
[string]$Plugin
|
||||
)
|
||||
$matching = @($Events | Where-Object {
|
||||
$_.e -ceq $Name -and (
|
||||
-not $PSBoundParameters.ContainsKey('Plugin') -or
|
||||
$_.plugin -ceq $Plugin)
|
||||
})
|
||||
if ($matching.Count -ne 1) {
|
||||
throw "expected one '$Name' status event, observed $($matching.Count)"
|
||||
}
|
||||
return $matching[0]
|
||||
}
|
||||
|
||||
function Invoke-Scenario {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Name,
|
||||
[Parameter(Mandatory = $true)][int]$ExpectedState,
|
||||
[Parameter(Mandatory = $true)][string]$ExpectedPackId,
|
||||
[AllowNull()][string]$ExpectedPackVersion,
|
||||
[Parameter(Mandatory = $true)][string]$ExpectedPreset,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateSet('pluginLoaded', 'pluginFailed')]
|
||||
[string]$ExpectedPluginEvent,
|
||||
[string]$ExpectedFailureFragment,
|
||||
[Parameter(Mandatory = $true)][string]$ExpectedPersistedPackId
|
||||
)
|
||||
Assert-ConnectedGateSafeLeafName $Name
|
||||
$scenarioRoot = Assert-ConnectedGateContainedPath $root (Join-Path $root $Name)
|
||||
$null = New-Item -ItemType Directory -Path $scenarioRoot
|
||||
Assert-ConnectedGateNoReparsePoint $scenarioRoot
|
||||
$stdout = Join-Path $scenarioRoot 'client.stdout.log'
|
||||
$stderr = Join-Path $scenarioRoot 'client.stderr.log'
|
||||
$status = Assert-ConnectedGateContainedPath $renderPackGate.StateDirectory (
|
||||
Join-Path $renderPackGate.StateDirectory "status\$Name.jsonl")
|
||||
$sessionConfigPath = New-ConnectedGraphicalSessionConfig `
|
||||
-State $renderPackGate `
|
||||
-Account $Account `
|
||||
-Plugins @($packageId) `
|
||||
-StatusFile $status
|
||||
$client = $null
|
||||
try {
|
||||
$env:ACDREAM_AUTOMATION_ARTIFACT_DIR = $scenarioRoot
|
||||
$client = Start-Process -FilePath $exe -WorkingDirectory $Repository `
|
||||
-ArgumentList @('--session-config', ('"' + $sessionConfigPath + '"')) `
|
||||
-RedirectStandardOutput $stdout -RedirectStandardError $stderr -PassThru
|
||||
Wait-ForLogPattern $client $stdout 'live: in world' $LoginTimeoutSeconds
|
||||
Wait-ForLogPattern $client $stdout `
|
||||
'[world-gate] screenshot-complete name=package-lifecycle' 120
|
||||
Wait-ForLogPattern $client $stdout `
|
||||
'[world-gate] checkpoint name=package-lifecycle' 30
|
||||
Close-ClientGracefully $client
|
||||
if ($client.ExitCode -ne 0) {
|
||||
throw "client exited with code $($client.ExitCode)"
|
||||
}
|
||||
|
||||
$metadataPath = Join-Path $scenarioRoot `
|
||||
'screenshots\package-lifecycle.metadata.json'
|
||||
if (-not (Test-Path -LiteralPath $metadataPath)) {
|
||||
throw "render-pack metadata is missing: '$metadataPath'"
|
||||
}
|
||||
$metadata = Get-Content -Raw -LiteralPath $metadataPath | ConvertFrom-Json
|
||||
$actual = $metadata.RenderPack
|
||||
if ([int]$metadata.SchemaVersion -ne 1) {
|
||||
throw "metadata schema was $($metadata.SchemaVersion), expected 1"
|
||||
}
|
||||
foreach ($comparison in @(
|
||||
@('State', [int]$ExpectedState, [int]$actual.State),
|
||||
@('PackId', $ExpectedPackId, [string]$actual.PackId),
|
||||
@('PackVersion', [string]$ExpectedPackVersion, [string]$actual.PackVersion),
|
||||
@('PresetId', $ExpectedPreset, [string]$actual.PresetId))) {
|
||||
if ($comparison[1] -cne $comparison[2]) {
|
||||
throw "$($comparison[0]) '$($comparison[2])', expected '$($comparison[1])'"
|
||||
}
|
||||
}
|
||||
if ([string]::IsNullOrWhiteSpace($ExpectedFailureFragment)) {
|
||||
if (-not [string]::IsNullOrWhiteSpace([string]$actual.FailureReason)) {
|
||||
throw "unexpected render-pack failure: $($actual.FailureReason)"
|
||||
}
|
||||
}
|
||||
elseif ([string]$actual.FailureReason -notlike "*$ExpectedFailureFragment*") {
|
||||
throw "failure '$($actual.FailureReason)' did not contain '$ExpectedFailureFragment'"
|
||||
}
|
||||
|
||||
$events = @(Read-StatusEvents $status)
|
||||
$pluginEvent = Assert-SingleStatusEvent `
|
||||
-Events $events -Name $ExpectedPluginEvent -Plugin $packageId
|
||||
foreach ($eventName in @('started', 'connected', 'characterList',
|
||||
'enteredWorld', 'disconnected', 'exited')) {
|
||||
$null = Assert-SingleStatusEvent -Events $events -Name $eventName
|
||||
}
|
||||
$exitEvent = Assert-SingleStatusEvent -Events $events -Name 'exited'
|
||||
if ([int]$exitEvent.code -ne 0) {
|
||||
throw "terminal status exit code was $($exitEvent.code)"
|
||||
}
|
||||
$persisted = (Get-Content -Raw -LiteralPath (
|
||||
Join-Path $renderPackGate.ConfigDirectory 'settings.json') |
|
||||
ConvertFrom-Json).display.renderPack
|
||||
if ([string]$persisted.packId -cne $ExpectedPersistedPackId) {
|
||||
throw "persisted pack '$($persisted.packId)', expected '$ExpectedPersistedPackId'"
|
||||
}
|
||||
|
||||
$pluginErrorProperty = $pluginEvent.PSObject.Properties['error']
|
||||
$result = [pscustomobject][ordered]@{
|
||||
Name = $Name
|
||||
Passed = $true
|
||||
ProcessId = $client.Id
|
||||
ExitCode = $client.ExitCode
|
||||
PluginEvent = $pluginEvent.e
|
||||
PluginError = if ($null -eq $pluginErrorProperty) {
|
||||
$null
|
||||
}
|
||||
else {
|
||||
$pluginErrorProperty.Value
|
||||
}
|
||||
RenderPack = [pscustomobject][ordered]@{
|
||||
State = $actual.State
|
||||
PackId = $actual.PackId
|
||||
PackVersion = $actual.PackVersion
|
||||
PresetId = $actual.PresetId
|
||||
EffectiveQuality = $actual.EffectiveQuality
|
||||
FailureReason = $actual.FailureReason
|
||||
ActivationGeneration = $actual.ActivationGeneration
|
||||
RetainedGpuBytes = $actual.RetainedGpuBytes
|
||||
TransientGpuBytes = $actual.TransientGpuBytes
|
||||
}
|
||||
PersistedPackId = $persisted.packId
|
||||
StatusFile = $status
|
||||
MetadataFile = $metadataPath
|
||||
}
|
||||
$results.Add($result)
|
||||
Write-Output (
|
||||
"PASS scenario=$Name plugin=$($pluginEvent.e) " +
|
||||
"renderPack=$($actual.PackId) state=$($actual.State)")
|
||||
}
|
||||
finally {
|
||||
if ($null -ne $client) {
|
||||
$client.Refresh()
|
||||
if (-not $client.HasExited) {
|
||||
$closed = $client.CloseMainWindow()
|
||||
if (-not $closed -or -not $client.WaitForExit(10000)) {
|
||||
Stop-Process -Id $client.Id -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
$client.Dispose()
|
||||
}
|
||||
if ($null -ne $sessionConfigPath) {
|
||||
Remove-ConnectedGraphicalSessionConfig `
|
||||
-State $renderPackGate -Path $sessionConfigPath
|
||||
$sessionConfigPath = $null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (@(Get-Process -Name AcDream.App -ErrorAction SilentlyContinue).Count -gt 0) {
|
||||
throw 'an AcDream.App client is already running; close it gracefully before the package gate'
|
||||
}
|
||||
if (@(Get-NetUDPEndpoint -LocalPort 9000 -ErrorAction SilentlyContinue).Count -eq 0) {
|
||||
throw 'local ACE is not listening on UDP port 9000'
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $route -PathType Leaf)) {
|
||||
throw "route file not found: '$route'"
|
||||
}
|
||||
if (-not $SkipBuild) {
|
||||
Write-Output 'Building Release solution...'
|
||||
& dotnet build (Join-Path $Repository 'AcDream.slnx') -c Release --no-restore
|
||||
if ($LASTEXITCODE -ne 0) { throw "Release build failed with exit code $LASTEXITCODE" }
|
||||
}
|
||||
foreach ($required in @($exe, $fixture)) {
|
||||
if (-not (Test-Path -LiteralPath $required -PathType Leaf)) {
|
||||
throw "required gate input not found: '$required'"
|
||||
}
|
||||
}
|
||||
|
||||
$null = New-Item -ItemType Directory -Path $root
|
||||
Assert-ConnectedGateNoReparsePoint $root
|
||||
$renderPackGate = New-ConnectedRenderPackGateState -Root $root -Preset retail
|
||||
try {
|
||||
$binaryIdentity = Get-ConnectedGateBinaryIdentity `
|
||||
-Repository $Repository -Executable $exe -SkipBuild:$SkipBuild
|
||||
$env:ACDREAM_DAT_DIR = "$env:USERPROFILE\Documents\Asheron's Call"
|
||||
$env:ACDREAM_LIVE = '1'
|
||||
$env:ACDREAM_TEST_HOST = '127.0.0.1'
|
||||
$env:ACDREAM_TEST_PORT = '9000'
|
||||
$env:ACDREAM_TEST_USER = $Account
|
||||
$env:ACDREAM_TEST_PASS = $Password
|
||||
$env:ACDREAM_RETAIL_UI = '1'
|
||||
$env:ACDREAM_DEVTOOLS = '0'
|
||||
$env:ACDREAM_UI_PROBE_DUMP = '0'
|
||||
$env:ACDREAM_UI_PROBE_SCRIPT = $route
|
||||
$env:ACDREAM_NO_AUDIO = '1'
|
||||
|
||||
$packageDirectory = Assert-ConnectedGateContainedPath `
|
||||
$renderPackGate.DataDirectory (
|
||||
Join-Path $renderPackGate.DataDirectory "plugins\$packageId")
|
||||
$withdrawnDirectory = Assert-ConnectedGateContainedPath $root (
|
||||
Join-Path $root 'withdrawn-package')
|
||||
|
||||
Install-Package -Directory $packageDirectory -Version '1.0.0'
|
||||
Write-Selection -Version '1.0.0' -Preset 'low'
|
||||
Invoke-Scenario -Name '01-installed-v1-selected' `
|
||||
-ExpectedState 2 -ExpectedPackId $packId -ExpectedPackVersion '1.0.0' `
|
||||
-ExpectedPreset 'low' -ExpectedPluginEvent pluginLoaded `
|
||||
-ExpectedPersistedPackId $packId
|
||||
|
||||
Write-PackageVersion -Directory $packageDirectory -Version '2.0.0'
|
||||
Write-Selection -Version '1.0.0' -Preset 'low'
|
||||
Invoke-Scenario -Name '02-updated-v2-stale-selection' `
|
||||
-ExpectedState 3 -ExpectedPackId 'retail' -ExpectedPackVersion $null `
|
||||
-ExpectedPreset 'off' -ExpectedPluginEvent pluginLoaded `
|
||||
-ExpectedFailureFragment 'version 1.0.0 was selected, but version 2.0.0 is installed' `
|
||||
-ExpectedPersistedPackId 'retail'
|
||||
|
||||
Write-Selection -Version '2.0.0' -Preset 'high'
|
||||
Invoke-Scenario -Name '03-updated-v2-selected' `
|
||||
-ExpectedState 2 -ExpectedPackId $packId -ExpectedPackVersion '2.0.0' `
|
||||
-ExpectedPreset 'high' -ExpectedPluginEvent pluginLoaded `
|
||||
-ExpectedPersistedPackId $packId
|
||||
|
||||
Move-Item -LiteralPath $packageDirectory -Destination $withdrawnDirectory
|
||||
Write-Selection -Version '2.0.0' -Preset 'high'
|
||||
Invoke-Scenario -Name '04-package-removed' `
|
||||
-ExpectedState 3 -ExpectedPackId 'retail' -ExpectedPackVersion $null `
|
||||
-ExpectedPreset 'off' -ExpectedPluginEvent pluginFailed `
|
||||
-ExpectedFailureFragment 'is not installed' `
|
||||
-ExpectedPersistedPackId 'retail'
|
||||
|
||||
Move-Item -LiteralPath $withdrawnDirectory -Destination $packageDirectory
|
||||
Set-Content -NoNewline -LiteralPath (
|
||||
Join-Path $packageDirectory 'throw-after-render-pack-register') -Value ''
|
||||
Write-Selection -Version '2.0.0' -Preset 'high'
|
||||
Invoke-Scenario -Name '05-registration-failed' `
|
||||
-ExpectedState 3 -ExpectedPackId 'retail' -ExpectedPackVersion $null `
|
||||
-ExpectedPreset 'off' -ExpectedPluginEvent pluginFailed `
|
||||
-ExpectedFailureFragment 'is not installed' `
|
||||
-ExpectedPersistedPackId 'retail'
|
||||
|
||||
Remove-Item -LiteralPath (
|
||||
Join-Path $packageDirectory 'throw-after-render-pack-register')
|
||||
Write-Selection -Version '2.0.0' -Preset 'high'
|
||||
Invoke-Scenario -Name '06-corrected-and-recovered' `
|
||||
-ExpectedState 2 -ExpectedPackId $packId -ExpectedPackVersion '2.0.0' `
|
||||
-ExpectedPreset 'high' -ExpectedPluginEvent pluginLoaded `
|
||||
-ExpectedPersistedPackId $packId
|
||||
}
|
||||
catch {
|
||||
$failure = $_.Exception.ToString()
|
||||
}
|
||||
finally {
|
||||
if ($null -ne $sessionConfigPath -and $null -ne $renderPackGate) {
|
||||
Remove-ConnectedGraphicalSessionConfig `
|
||||
-State $renderPackGate -Path $sessionConfigPath
|
||||
}
|
||||
if ($null -ne $renderPackGate) {
|
||||
Restore-ConnectedRenderPackGateEnvironment $renderPackGate
|
||||
}
|
||||
$report = [pscustomobject][ordered]@{
|
||||
Passed = [string]::IsNullOrWhiteSpace($failure) -and $results.Count -eq 6
|
||||
StartedUtc = $startedUtc
|
||||
FinishedUtc = [DateTime]::UtcNow.ToString('O')
|
||||
SourceCommit = if ($null -eq $binaryIdentity) {
|
||||
$null
|
||||
} else { $binaryIdentity.SourceCommit }
|
||||
BinaryProductVersion = if ($null -eq $binaryIdentity) {
|
||||
$null
|
||||
} else { $binaryIdentity.BinaryProductVersion }
|
||||
BinaryCommit = if ($null -eq $binaryIdentity) {
|
||||
$null
|
||||
} else { $binaryIdentity.BinaryCommit }
|
||||
BinaryMatchesSource = if ($null -eq $binaryIdentity) {
|
||||
$false
|
||||
} else { $binaryIdentity.BinaryMatchesSource }
|
||||
TrackedSourceStatus = if ($null -eq $binaryIdentity) {
|
||||
@()
|
||||
} else { @($binaryIdentity.SourceTrackedStatus) }
|
||||
PackageId = $packageId
|
||||
RenderPackId = $packId
|
||||
ScenarioCount = $results.Count
|
||||
Scenarios = @($results)
|
||||
Failure = $failure
|
||||
}
|
||||
$reportPath = Join-Path $root 'report.json'
|
||||
$report | ConvertTo-Json -Depth 12 |
|
||||
Set-Content -Encoding utf8 -LiteralPath $reportPath
|
||||
Write-Output "REPORT=$reportPath"
|
||||
Write-Output "RESULT=$(if ($report.Passed) { 'PASS' } else { 'FAIL' })"
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($failure)) {
|
||||
throw $failure
|
||||
}
|
||||
if ($results.Count -ne 6) {
|
||||
throw "package lifecycle completed $($results.Count) of 6 scenarios"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue