Skip to content

Error during handling of output-element with state based ToString() Implementation #2649

@NymanRobin

Description

@NymanRobin

Checklist

What is the issue?

Issue is very similar to the one described in #2421, however, it is quite special case which occurs to me when I use PowerCLI in a test to make an ephemeral test vm. In the PowerCLI the ToString implementation seems to throw when the VM has been deleted at the time of the serialization call when creating the Nunit3 report.

Here is the actual stack trace, I have simpler example to reproduce below:

System.Management.Automation.RuntimeException: Invoking step End failed:
Result 1 - Error 1:
Export-XmlReport: Exception calling "ToString" with "0" argument(s): "The object 'vim.VirtualMachine:634' has already been deleted or has
not been completely created"

at Write-NUnit3OutputElement, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 17770
at Write-NUnit3TestCaseElement, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 17706
at Write-NUnit3TestSuiteElement, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 17417
at Write-NUnit3TestSuiteElement, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 17376
at Write-NUnit3TestSuiteElement, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 17376
at Write-NUnit3TestRunChildNode, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 17279
at Write-NUnit3Report, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 17232
at Export-XmlReport, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 18078
at Export-PesterResult, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 17926
at <ScriptBlock>, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 18419
at Invoke-PluginStep, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 1800
at Invoke-Pester<End>, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 5141
at Invoke-WindowsTest, C:\Tools\install\PlatformTests\install.ps1: line 145
at <ScriptBlock>, C:\Tools\install\PlatformTests\install.ps1: line 310
at <ScriptBlock>, <No file>: line 12

at Assert-Success, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 1857
at Invoke-PluginStep, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 1819
at Invoke-Pester<End>, C:\Tools\install\PlatformTests\Modules\Pester\5.6.1\Pester.psm1: line 5141
at Invoke-WindowsTest, C:\Tools\install\PlatformTests\install.ps1: line 145
at <ScriptBlock>, C:\Tools\install\PlatformTests\install.ps1: line 310
at <ScriptBlock>, <No file>: line 12

Expected Behavior

As suggested in the old issue complete test result file is written. If there is errors during processing the output-element they could be skipped instead of throwing.

Steps To Reproduce

Here is a simple example that re-creates the PowerCLI behavior quite closely

class MyVm {
    [string]$Name
    [bool]$PowerState

    MyVm([string]$name, [string]$powerState=$true) {
        $this.Name = $name
        $this.PowerState = $powerState
    }

    [string] ToString() {
        if (-not $this.PowerState) {
            throw "Cannot convert VM '$($this.Name)' to string because it is powered off."
        }
        else {
            return "VM Name: $($this.Name), PowerState: $($this.PowerState)"
        }
    }
}

Describe "Custom virutlmachine test" {
    It "Turn off vm" {
        $vm = [MyVm]::new("TestVM1", "On")
        Write-Output $vm
        $vm.PowerState = $false
        $vm.PowerState | Should -Be $false
        $vm = $null
    }
}

Config:

$container = New-PesterContainer -Path "Test.Tests.ps1"
$testResultFile = "$PSScriptRoot\TestResult.xml"
$configPester = @{
    Run        = @{
        Exit      = $true
        PassThru  = $true
        Container = $container
    }
    Output     = @{
        Verbosity = 'Detailed'
    }
    TestResult = @{
        Enabled      = $true
        OutputFormat = 'NUnit3'
        OutputPath   = $testResultFile
    }
    Should     = @{
        ErrorAction = 'Stop'
    }
}

$testResults = Invoke-Pester -Configuration $configPester

Describe your environment

Pester version : 5.6.1
PowerShell version : 7.4.10
OS version : Microsoft Windows NT 10.0.26100.0

Possible Solution?

Even though this is quite special case and you could argue that the PowerCLI way of serializing is not the nicest, I think it would be better to keep processing the output instead throwing. So my best idea is to implement a exception catching

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions