diff --git a/scripts/PowerShellLogging.ps1 b/scripts/PowerShellLogging.ps1 index 9d76b441..b869c8f6 100644 --- a/scripts/PowerShellLogging.ps1 +++ b/scripts/PowerShellLogging.ps1 @@ -89,8 +89,12 @@ function Assert-WelaPsLoggingCapacity { param($Snapshot,[array]$Definitions) # Project predictable inventory growth before writing; new inherited access descriptors # still require native readback. Projection never mutates the captured original state. - $tree=ConvertTo-WelaPsLoggingKey $Snapshot.Machine|ConvertFrom-Json;$rows=@{} - foreach($row in $tree.Keys){$rows[$row.Path]=$row} + # JSON round-trips can reinterpret literal ISO-date registry strings as DateTime. + $tree=[pscustomobject]@{Exists=$Snapshot.Machine.Exists;Keys=@()};$rows=@{} + foreach($row in $Snapshot.Machine.Keys){ + $values=@(foreach($entry in $row.Values){$data=$entry.Value;if($data -is [Array]){$data=$data.Clone()};[pscustomobject]@{Name=$entry.Name;Type=$entry.Type;Value=$data}}) + $rows[$row.Path]=[pscustomobject]@{Path=$row.Path;Values=$values;Children=@($row.Children);Access=$row.Access} + } foreach($definition in $Definitions){ $paths=@('');$path='';foreach($part in $definition.Path.Split('\')){$path=if($path){$path+'\'+$part}else{$part};$paths+=$path} foreach($path in $paths){ diff --git a/tests/PowerShellLogging.Tests.ps1 b/tests/PowerShellLogging.Tests.ps1 index 1fe04866..09276941 100644 --- a/tests/PowerShellLogging.Tests.ps1 +++ b/tests/PowerShellLogging.Tests.ps1 @@ -75,6 +75,13 @@ try { Assert ((ConvertTo-WelaPsLoggingKey $script:observed.Machine).Length -eq 1048576) 'Character-cap boundary fixture fits the current reader exactly' $capacity=Invoke-WelaPowerShellLogging -Action Configure -Control Module -ModuleName NewModule -Auto -BackupPath (Join-Path $root 'character-capacity') Assert ($capacity.ExitCode -eq 1 -and $script:writes -eq 0 -and -not (Test-Path (Join-Path $root 'character-capacity'))) 'Predictable serialized-value growth beyond character cap is refused before writes' + $literalSnapshot=Fixture;$row=@($literalSnapshot.Machine.Keys|Where-Object Path -eq Transcription)[0] + $row.Values+=@(1..64|ForEach-Object{[pscustomobject]@{Name=('LiteralDate'+$_);Type='String';Value='2026-09-21T00:00:00.000Z'}}) + $row.Values+=[pscustomobject]@{Name='LiteralBytes';Type='Binary';Value=[byte[]]@(0,127,255)},[pscustomobject]@{Name='LiteralStrings';Type='MultiString';Value=[string[]]@('2026-09-21T00:00:00.000Z','')};$row.Values+=[pscustomobject]@{Name='LiteralFiller';Type='String';Value=''};$space=1048576-(ConvertTo-WelaPsLoggingKey $literalSnapshot.Machine).Length;$row.Values[-1].Value='x'*$space + $literalBefore=ConvertTo-WelaPsLoggingKey $literalSnapshot + Reject {Assert-WelaPsLoggingCapacity $literalSnapshot @(Get-WelaPsLoggingDefinitions @('Module') @('NewModule'))} 'character capacity' + Assert ((ConvertTo-WelaPsLoggingKey $literalSnapshot) -ceq $literalBefore -and $row.Values[1].Value -is [string]) 'Capacity projection preserves literal ISO strings and the caller snapshot' + Assert (($row.Values|Where-Object Name -eq LiteralBytes).Value -is [byte[]] -and ($row.Values|Where-Object Name -eq LiteralStrings).Value -is [string[]]) 'Projection retains typed binary and multi-string caller data' Reset;$script:failWrite=$true;$failed=Invoke-WelaPowerShellLogging -Action Configure -Control Module,ScriptBlock -ModuleName Microsoft.PowerShell.Utility -Auto -BackupPath (Join-Path $root 'writefailure') Assert ($failed.ExitCode -eq 1 -and $script:writes -eq 1 -and @($failed.Results|Where-Object Status -eq Skipped).Count -eq 2) 'Native failure stops and explicitly reports later writes' Reset;$script:corrupt=$true;$failed=Invoke-WelaPowerShellLogging -Action Configure -Control Module,ScriptBlock -ModuleName Microsoft.PowerShell.Utility -Auto -BackupPath (Join-Path $root 'corrupt')