fix(gates): select a character in connected graphical runs

This commit is contained in:
Erik 2026-08-22 13:24:39 +02:00
parent 7a5f96ede5
commit 0b6c6557a8
4 changed files with 107 additions and 2 deletions

View file

@ -125,6 +125,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'
$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
[Environment]::GetEnvironmentVariable($_, 'Process') -ne $null
@ -141,11 +143,16 @@ $unsafeLeafRejected=$false
try {{ Assert-ConnectedGateSafeLeafName '../escape' }} catch {{ $unsafeLeafRejected=$true }}
$escapeRejected=$false
try {{ Assert-ConnectedGateContainedPath {rootQuoted} (Join-Path {rootQuoted} '..\escape') }} catch {{ $escapeRejected=$true }}
Remove-ConnectedGraphicalSessionConfig -State $state -Path $sessionConfigPath
[pscustomobject]@{{
Password=$env:ACDREAM_TEST_PASS; User=$env:ACDREAM_TEST_USER;
Config=$env:ACDREAM_CONFIG_DIR; History=$env:ACDREAM_FRAME_HISTORY;
Future=$env:ACDREAM_FUTURE_GATE_KNOB; Isolated=$isolated; Mismatches=$mismatches;
UnsafeLeafRejected=$unsafeLeafRejected; EscapeRejected=$escapeRejected;
SessionConfigRemoved=(-not (Test-Path -LiteralPath $sessionConfigPath));
SessionCharacterIndex=$sessionConfig.sessions[0].character.index;
SessionCredentialProvider=$sessionConfig.sessions[0].credential.provider;
SessionCredentialReference=$sessionConfig.sessions[0].credential.reference;
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));
@ -159,11 +166,32 @@ try {{ Assert-ConnectedGateContainedPath {rootQuoted} (Join-Path {rootQuoted} '.
Assert.Empty(rootElement.GetProperty("Mismatches").EnumerateArray());
Assert.True(rootElement.GetProperty("UnsafeLeafRejected").GetBoolean());
Assert.True(rootElement.GetProperty("EscapeRejected").GetBoolean());
Assert.True(rootElement.GetProperty("SessionConfigRemoved").GetBoolean());
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("medium", rootElement.GetProperty("Settings").GetString());
}
finally { Directory.Delete(root, recursive: true); }
}
[Fact]
public void ConnectedGraphicalGatesSelectTheFirstCharacterThroughSessionConfig()
{
foreach (string scriptName in new[] { LifecycleScript, SoakScript })
{
string source = ReadTool(scriptName);
Assert.Contains("New-ConnectedGraphicalSessionConfig", source, StringComparison.Ordinal);
Assert.Contains("-ArgumentList @('--session-config'", source, StringComparison.Ordinal);
Assert.Contains("Remove-ConnectedGraphicalSessionConfig", source, StringComparison.Ordinal);
}
string common = ReadTool(CommonScript);
Assert.Contains("character = [ordered]@{ index = $CharacterIndex }", common, StringComparison.Ordinal);
Assert.Contains("provider = 'Environment'", common, StringComparison.Ordinal);
Assert.Contains("reference = $CredentialEnvironmentVariable", common, StringComparison.Ordinal);
}
[Fact]
public void EveryConnectedScreenshotMustProveExactFailureFreeActivation()
{

View file

@ -160,6 +160,63 @@ function Restore-ConnectedRenderPackGateEnvironment {
}
}
function New-ConnectedGraphicalSessionConfig {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)][object]$State,
[Parameter(Mandatory = $true)][string]$Account,
[string]$HostName = '127.0.0.1',
[ValidateRange(1, 65535)][int]$Port = 9000,
[ValidateRange(0, [int]::MaxValue)][int]$CharacterIndex = 0,
[string]$CredentialEnvironmentVariable = 'ACDREAM_TEST_PASS'
)
if ([string]::IsNullOrWhiteSpace($Account)) {
throw 'Connected graphical session account cannot be empty.'
}
if ([string]::IsNullOrWhiteSpace($HostName)) {
throw 'Connected graphical session host cannot be empty.'
}
if ($CredentialEnvironmentVariable -notmatch '^[A-Za-z_][A-Za-z0-9_]*$') {
throw "Unsafe credential environment-variable name '$CredentialEnvironmentVariable'."
}
$path = Assert-ConnectedGateContainedPath $State.StateDirectory (
Join-Path $State.StateDirectory 'graphical-session.json')
if (Test-Path -LiteralPath $path) {
throw "Connected graphical session config already exists: '$path'."
}
[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
}
})
} | ConvertTo-Json -Depth 8 |
Set-Content -LiteralPath $path -Encoding utf8
return $path
}
function Remove-ConnectedGraphicalSessionConfig {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)][object]$State,
[Parameter(Mandatory = $true)][string]$Path
)
$containedPath = Assert-ConnectedGateContainedPath $State.StateDirectory $Path
if (Test-Path -LiteralPath $containedPath -PathType Leaf) {
Remove-Item -LiteralPath $containedPath -Force
}
}
function Get-ConnectedGateBinaryIdentity {
[CmdletBinding()]
param([Parameter(Mandatory = $true)][string]$Repository,

View file

@ -730,6 +730,9 @@ $renderPackGate = New-ConnectedRenderPackGateState `
-Root $artifactDir `
-Preset $RenderPackPreset `
-SettingOverrides $RenderPackSettingOverrides
$sessionConfigPath = New-ConnectedGraphicalSessionConfig `
-State $renderPackGate `
-Account $Account
try {
$binaryIdentity = Get-ConnectedGateBinaryIdentity `
-Repository $Repository -Executable $exe -SkipBuild:$SkipBuild
@ -805,6 +808,7 @@ $envDisclosure | ConvertTo-Json -Depth 4 |
try {
$process = Start-Process -FilePath $exe -WorkingDirectory $Repository `
-ArgumentList @('--session-config', ('"' + $sessionConfigPath + '"')) `
-RedirectStandardOutput $stdoutLog -RedirectStandardError $stderrLog -PassThru
Write-Marker (
"launch pid=$($process.Id) binaryCommit=$commit sourceCommit=$sourceCommit " +
@ -1055,7 +1059,13 @@ finally {
}
}
finally {
Restore-ConnectedRenderPackGateEnvironment $renderPackGate
try {
Remove-ConnectedGraphicalSessionConfig `
-State $renderPackGate -Path $sessionConfigPath
}
finally {
Restore-ConnectedRenderPackGateEnvironment $renderPackGate
}
}
if ($failures.Count -gt 0) { exit 1 }

View file

@ -287,6 +287,7 @@ function Invoke-Session(
try {
$client = Start-Process -FilePath $exe -WorkingDirectory $Repository `
-ArgumentList @('--session-config', ('"' + $sessionConfigPath + '"')) `
-RedirectStandardOutput $stdout -RedirectStandardError $stderr -PassThru
Wait-ForPattern $client $stdout '[UI-PROBE] UI probe script complete' $SessionTimeoutSeconds
@ -558,6 +559,9 @@ $renderPackGate = New-ConnectedRenderPackGateState `
-Root $root `
-Preset $RenderPackPreset `
-SettingOverrides $RenderPackSettingOverrides
$sessionConfigPath = New-ConnectedGraphicalSessionConfig `
-State $renderPackGate `
-Account $Account
try {
if (@(Get-Process -Name AcDream.App -ErrorAction SilentlyContinue).Count -gt 0) {
throw 'an AcDream.App client is already running; close it gracefully before the gate'
@ -683,7 +687,13 @@ try {
foreach ($warning in $warnings) { Write-Output "WARNING=$warning" }
}
finally {
Restore-ConnectedRenderPackGateEnvironment $renderPackGate
try {
Remove-ConnectedGraphicalSessionConfig `
-State $renderPackGate -Path $sessionConfigPath
}
finally {
Restore-ConnectedRenderPackGateEnvironment $renderPackGate
}
}
if ($failures.Count -gt 0) { exit 1 }