Pester icon indicating copy to clipboard operation
Pester copied to clipboard

Pester tests failing in Docker container in Jenkins job

Open dorenstein opened this issue 2 months ago • 1 comments

Checklist

What is the issue?

I have created several Pester tests of scripts that I use to build our product installers on Jenkins, in a Docker container. These tests all pass outside of Jenkins and were invoked, passing on the Jenkins server as well. Suddenly they stopped working right when I call New-PesterContainer from my executive script. I narrow down the test by invoking only one test, but I believe it is failing even before the test is invoked. Here is the point of failure: DEBUG: 3041+ >>>> $type, $item = switch ($PSCmdlet.ParameterSetName) { DEBUG: ! SET $switch = 'IEnumerator'. DEBUG: 3041+ $type, $item = switch ( >>>> $PSCmdlet.ParameterSetName) { DEBUG: 3042+ >>>> 'ScriptBlock' { 'ScriptBlock', $ScriptBlock } DEBUG: 3043+ >>>> 'Path' { 'File', (& $SafeCommands['Get-Item'] $Path) } DEBUG: 3044+ >>>> 'File' { 'File', $File } DEBUG: 3044+ 'File' { >>>> 'File', $File } DEBUG: 3045+ >>>> 'Container' { $Container.Type, $Container.Item } DEBUG: 3041+ $type, $item = switch ( >>>> $PSCmdlet.ParameterSetName) { DEBUG: ! SET $switch = ''. DEBUG: ! SET $type = 'File'. DEBUG: ! SET $item = 'C:\devsecops\workspace\ch_Dev_installer-build_OVHI-2553...'. DEBUG: 3049+ >>>> $c = [Pester.ContainerInfo]::Create() DEBUG: ! SET $foreach = 'IEnumerator'. DEBUG: ! SET $foreach = ''. DEBUG: ! SET $foreach = 'IEnumerator'. DEBUG: ! SET $foreach = ''. DEBUG: 1+ & {try {& 'c:\devsecops\workspace\ch_Dev_installer-build_OVHI-2553@tmp\durable-fa74dde6\p owershellScript.ps1'} catch { >>>> throw}; exit $LASTEXITCODE} powershell.exe : New-BlockContainerObject : Cannot convert value to type System.String. At C:\devsecops\workspace\ch_Dev_installer-build_OVHI-2553@tmp\durable-fa74dde6\powershellWrapper.ps1:3 char:1

  • & powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Comm ...
  •   + CategoryInfo          : NotSpecified: (New-BlockContai... System.String.    :String) [], RemoteException
      + FullyQualifiedErrorId : NativeCommandError
    
    

At C:\Program Files\WindowsPowerShell\Modules\Pester\5.7.1\Pester.psm1:4141 char:17

  •             New-BlockContainerObject -File $file -Data $d
    
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidArgument: (:) [New-BlockContainerObject], RuntimeException
    • FullyQualifiedErrorId : InvalidCastFromAnyTypeToString,New-BlockContaine rObject RIGHT Around this Pester code, where the coder says "some voodoo"

    it seems that when I don't assign $Data to $dt here the foreach does not always work in 5.1 :/ some voodoo

    $dt = $Data

    expand to ContainerInfo user can provide multiple sets of data, but ContainerInfo can hold only one

    to keep the internal logic simple.

    $kind = $PSCmdlet.ParameterSetName if ('ScriptBlock' -eq $kind) { # the @() is significant here, it will make it iterate even if there are no data # which allows scriptblocks without data to run foreach ($d in @($dt)) { foreach ($sb in $ScriptBlock) { New-BlockContainerObject -ScriptBlock $sb -Data $d } } }

    if ("Path" -eq $kind) { # resolve the path we are given in the same way we would resolve -Path on Invoke-Pester $files = @(Find-File -Path $Path -ExcludePath $PesterPreference.Run.ExcludePath.Value -Extension $PesterPreference.Run.TestExtension.Value) foreach ($file in $files) { # the @() is significant here, it will make it iterate even if there are no data # which allows files without data to run foreach ($d in @($dt)) { New-BlockContainerObject -File $file -Data $d } } }

Here is the executive script snippet: $( $UTFunctions = @{ NewUpgradeScript= @(,"CompareRevs") } foreach ($key in $UTFunctions.Keys) { if (Test-Path "$key.ps1") { $TestArray = $UTFunctions[$key] foreach ($Value in $TestArray) {

        $TestFilePath = ".\PesterUnitTests\$Value.Tests.ps1"
        if (Test-Path $TestFilePath)
        {
            Write-Output "Unit test of $Value in $key"
            # Jump through hoops to pass param to Unit test.
            $container = New-PesterContainer -Path $TestFilePath -Data @{ ScriptWithFuncions = "..\NewUpgradeScript"} 
            Invoke-Pester -Container $container
        }

    }
} 

} Also, on the build server, I have to installer Pester 5.7. This is what I had to do: Set-ExecutionPolicy Bypass -Scope Process -Force [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force

Install-Module -Name Pester -Force -SkipPublisherCheck -Confirm:$false

Expected Behavior

The Pester container should be created successfully, and the Pester tests should be run successfully.

Steps To Reproduce

All of the steps are described above.

Describe your environment

Jenkins, Docker container for the job, Pester 5.7, Powershell 5.1

Possible Solution?

No response

dorenstein avatar Nov 01 '25 17:11 dorenstein

Is the code running in docker? In that case it should be easy to repro locally? Do you have an image / docker file that shows this problem?

nohwnd avatar Nov 06 '25 08:11 nohwnd