Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
ThreadJob.Tests.ps1421 linesDownload Raw Back to ThreadJob
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3 4# Helper function to wait for job to reach a running or completed state5# Job state can go to "Running" before the underlying runspace thread is running6# so we always first wait 100 mSec before checking state.7function Wait-ForJobRunning8{9    param (10        $job11    )12 13    $iteration = 1014    Do15    {16        Start-Sleep -Milliseconds 10017    }18    Until (($job.State -match "Running|Completed|Failed") -or (--$iteration -eq 0))19 20    if ($job.State -notmatch "Running|Completed|Failed")21    {22        throw ("Cannot start job '{0}'. Job state is '{1}'" -f $job,$job.State)23    }24}25 26Describe 'Basic ThreadJob Tests' -Tags 'CI' {27 28    BeforeAll {29 30        $scriptFilePath1 = Join-Path $testdrive "TestThreadJobFile1.ps1"31        @'32        for ($i=0; $i -lt 10; $i++)33        {34            Write-Output "Hello $i"35        }36'@ > $scriptFilePath137 38        $scriptFilePath2 = Join-Path $testdrive "TestThreadJobFile2.ps1"39        @'40        param ($arg1, $arg2)41        Write-Output $arg142        Write-Output $arg243'@ > $scriptFilePath244 45        $scriptFilePath3 = Join-Path $testdrive "TestThreadJobFile3.ps1"46        @'47        $input | foreach {48            Write-Output $_49        }50'@ > $scriptFilePath351 52        $scriptFilePath4 = Join-Path $testdrive "TestThreadJobFile4.ps1"53        @'54        Write-Output $using:Var155        Write-Output $($using:Array1)[2]56        Write-Output @(,$using:Array1)57'@ > $scriptFilePath458 59        $scriptFilePath5 = Join-Path $testdrive "TestThreadJobFile5.ps1"60        @'61        param ([string]$param1)62        Write-Output "$param1 $using:Var1 $using:Var2"63'@ > $scriptFilePath564 65        $WaitForCountFnScript = @'66        function Wait-ForExpectedRSCount67        {68            param (69                $expectedRSCount70            )71 72            $iteration = 2073            while ((@(Get-Runspace).Count -ne $expectedRSCount) -and ($iteration-- -gt 0))74            {75                Start-Sleep -Milliseconds 10076            }77        }78'@79    }80 81    AfterEach {82        Get-Job | Where-Object PSJobTypeName -EQ "ThreadJob" | Remove-Job -Force83    }84 85    It 'ThreadJob with ScriptBlock' {86 87        $job = Start-ThreadJob -ScriptBlock { "Hello" }88        $results = $job | Receive-Job -Wait89        $results | Should -Be "Hello"90    }91 92    It 'ThreadJob with ScriptBlock and Initialization script' {93 94        $job = Start-ThreadJob -ScriptBlock { "Goodbye" } -InitializationScript { "Hello" }95        $results = $job | Receive-Job -Wait96        $results[0] | Should -Be "Hello"97        $results[1] | Should -Be "Goodbye"98    }99 100    It 'ThreadJob with ScriptBlock and Argument list' {101 102        $job = Start-ThreadJob -ScriptBlock { param ($arg1, $arg2) $arg1; $arg2 } -ArgumentList @("Hello","Goodbye")103        $results = $job | Receive-Job -Wait104        $results[0] | Should -Be "Hello"105        $results[1] | Should -Be "Goodbye"106    }107 108    It 'ThreadJob with ScriptBlock and piped input' {109 110        $job = "Hello","Goodbye" | Start-ThreadJob -ScriptBlock { $input | ForEach-Object { $_ } }111        $results = $job | Receive-Job -Wait112        $results[0] | Should -Be "Hello"113        $results[1] | Should -Be "Goodbye"114    }115 116    It 'ThreadJob with ScriptBlock and Using variables' {117 118        $Var1 = "Hello"119        $Var2 = "Goodbye"120        $Var3 = 102121        $Var4 = 1..5122        $global:GVar1 = "GlobalVar"123        $job = Start-ThreadJob -ScriptBlock {124            Write-Output $using:Var1125            Write-Output $using:Var2126            Write-Output $using:Var3127            Write-Output ($using:Var4)[1]128            Write-Output @(,$using:Var4)129            Write-Output $using:GVar1130        }131 132        $results = $job | Receive-Job -Wait133        $results[0] | Should -Be $Var1134        $results[1] | Should -Be $Var2135        $results[2] | Should -Be $Var3136        $results[3] | Should -Be 2137        $results[4] | Should -Be $Var4138        $results[5] | Should -Be $global:GVar1139    }140 141    It 'ThreadJob with ScriptBlock and Using variables and argument list' {142 143        $Var1 = "Hello"144        $Var2 = 52145        $job = Start-ThreadJob -ScriptBlock {146            param ([string] $param1)147 148            "$using:Var1 $param1 $using:Var2"149        } -ArgumentList "There"150 151        $results = $job | Receive-Job -Wait152        $results | Should -Be "Hello There 52"153    }154 155    It 'ThreadJob with ScriptFile' {156 157        $job = Start-ThreadJob -FilePath $scriptFilePath1158        $results = $job | Receive-Job -Wait159        $results | Should -HaveCount 10160        $results[9] | Should -Be "Hello 9"161    }162 163    It 'ThreadJob with ScriptFile and Initialization script' {164 165        $job = Start-ThreadJob -FilePath $scriptFilePath1 -Initialization { "Goodbye" }166        $results = $job | Receive-Job -Wait167        $results | Should -HaveCount 11168        $results[0] | Should -Be "Goodbye"169    }170 171    It 'ThreadJob with ScriptFile and Argument list' {172 173        $job = Start-ThreadJob -FilePath $scriptFilePath2 -ArgumentList @("Hello","Goodbye")174        $results = $job | Receive-Job -Wait175        $results[0] | Should -Be "Hello"176        $results[1] | Should -Be "Goodbye"177    }178 179    It 'ThreadJob with ScriptFile and piped input' {180 181        $job = "Hello","Goodbye" | Start-ThreadJob -FilePath $scriptFilePath3182        $results = $job | Receive-Job -Wait183        $results[0] | Should -Be "Hello"184        $results[1] | Should -Be "Goodbye"185    }186 187    It 'ThreadJob with ScriptFile and Using variables' {188 189        $Var1 = "Hello!"190        $Array1 = 1..10191 192        $job = Start-ThreadJob -FilePath $scriptFilePath4193        $results = $job | Receive-Job -Wait194        $results[0] | Should -Be $Var1195        $results[1] | Should -Be 3196        $results[2] | Should -Be $Array1197    }198 199    It 'ThreadJob with ScriptFile and Using variables with argument list' {200 201        $Var1 = "There"202        $Var2 = 60203        $job = Start-ThreadJob -FilePath $scriptFilePath5 -ArgumentList "Hello"204        $results = $job | Receive-Job -Wait205        $results | Should -Be "Hello There 60"206    }207 208    It 'ThreadJob with terminating error' {209 210        $job = Start-ThreadJob -ScriptBlock { throw "MyError!" }211        $job | Wait-Job212        $job.JobStateInfo.Reason.Message | Should -Be "MyError!"213    }214 215    It 'ThreadJob and Error stream output' {216 217        $job = Start-ThreadJob -ScriptBlock { Write-Error "ErrorOut" } | Wait-Job218        $job.Error | Should -Be "ErrorOut"219    }220 221    It 'ThreadJob and Warning stream output' {222 223        $job = Start-ThreadJob -ScriptBlock { Write-Warning "WarningOut" } | Wait-Job224        $job.Warning | Should -Be "WarningOut"225    }226 227    It 'ThreadJob and Verbose stream output' {228 229        $job = Start-ThreadJob -ScriptBlock { $VerbosePreference = 'Continue'; Write-Verbose "VerboseOut" } | Wait-Job230        $job.Verbose | Should -Match "VerboseOut"231    }232 233    It 'ThreadJob and Verbose stream output' {234 235        $job = Start-ThreadJob -ScriptBlock { $DebugPreference = 'Continue'; Write-Debug "DebugOut" } | Wait-Job236        $job.Debug | Should -Be "DebugOut"237    }238 239    It 'ThreadJob ThrottleLimit and Queue' {240 241        try242        {243            # Start four thread jobs with ThrottleLimit set to two244            Get-Job | Where-Object PSJobTypeName -EQ "ThreadJob" | Remove-Job -Force245            $job1 = Start-ThreadJob -ScriptBlock { Start-Sleep -Seconds 60 } -ThrottleLimit 2246            $job2 = Start-ThreadJob -ScriptBlock { Start-Sleep -Seconds 60 }247            $job3 = Start-ThreadJob -ScriptBlock { Start-Sleep -Seconds 60 }248            $job4 = Start-ThreadJob -ScriptBlock { Start-Sleep -Seconds 60 }249 250            # Allow jobs to start251            Wait-ForJobRunning $job2252 253            Get-Job | Where-Object { ($_.PSJobTypeName -eq "ThreadJob") -and ($_.State -eq "Running") } | Should -HaveCount 2254            Get-Job | Where-Object { ($_.PSJobTypeName -eq "ThreadJob") -and ($_.State -eq "NotStarted") } | Should -HaveCount 2255        }256        finally257        {258            Get-Job | Where-Object PSJobTypeName -EQ "ThreadJob" | Remove-Job -Force259        }260 261        Get-Job | Where-Object PSJobTypeName -EQ "ThreadJob" | Should -HaveCount 0262    }263 264    It 'ThreadJob Runspaces should be cleaned up at completion' {265 266        $script = $WaitForCountFnScript + @'267        $WarningPreference = 'SilentlyContinue'268        try269        {270            Get-Job | Where-Object PSJobTypeName -eq "ThreadJob" | Remove-Job -Force271            $rsStartCount = @(Get-Runspace).Count272 273            # Start four thread jobs with ThrottleLimit set to two274            $Job1 = Start-ThreadJob -ScriptBlock { "Hello 1!" } -ThrottleLimit 5275            $job2 = Start-ThreadJob -ScriptBlock { "Hello 2!" }276            $job3 = Start-ThreadJob -ScriptBlock { "Hello 3!" }277            $job4 = Start-ThreadJob -ScriptBlock { "Hello 4!" }278 279            $null = $job1,$job2,$job3,$job4 | Wait-Job280 281            # Allow for runspace clean up to happen282            Wait-ForExpectedRSCount $rsStartCount283 284            Write-Output (@(Get-Runspace).Count -eq $rsStartCount)285        }286        finally287        {288            Get-Job | Where-Object PSJobTypeName -eq "ThreadJob" | Remove-Job -Force289        }290'@291 292        $result = & "$PSHOME/pwsh" -c $script293        $result | Should -BeExactly "True"294    }295 296    It 'ThreadJob Runspaces should be cleaned up after job removal' {297 298    $script = $WaitForCountFnScript + @'299        $WarningPreference = 'SilentlyContinue'300        try {301            Get-Job | Where-Object PSJobTypeName -eq "ThreadJob" | Remove-Job -Force302            $rsStartCount = @(Get-Runspace).Count303 304            # Start four thread jobs with ThrottleLimit set to two305            $Job1 = Start-ThreadJob -ScriptBlock { Start-Sleep -Seconds 60 } -ThrottleLimit 2306            $job2 = Start-ThreadJob -ScriptBlock { Start-Sleep -Seconds 60 }307            $job3 = Start-ThreadJob -ScriptBlock { Start-Sleep -Seconds 60 }308            $job4 = Start-ThreadJob -ScriptBlock { Start-Sleep -Seconds 60 }309 310            Wait-ForExpectedRSCount ($rsStartCount + 4)311            Write-Output (@(Get-Runspace).Count -eq ($rsStartCount + 4))312 313            # Stop two jobs314            $job1 | Remove-Job -Force315            $job3 | Remove-Job -Force316 317            Wait-ForExpectedRSCount ($rsStartCount + 2)318            Write-Output (@(Get-Runspace).Count -eq ($rsStartCount + 2))319        }320        finally321        {322            Get-Job | Where-Object PSJobTypeName -eq "ThreadJob" | Remove-Job -Force323        }324 325        Wait-ForExpectedRSCount $rsStartCount326        Write-Output (@(Get-Runspace).Count -eq $rsStartCount)327'@328 329        $result = & "$PSHOME/pwsh" -c $script330        $result | Should -BeExactly "True","True","True"331    }332 333    It 'ThreadJob jobs should work with Receive-Job -AutoRemoveJob' {334 335        Get-Job | Where-Object PSJobTypeName -EQ "ThreadJob" | Remove-Job -Force336 337        $job1 = Start-ThreadJob -ScriptBlock { 1..2 | ForEach-Object { Start-Sleep -Milliseconds 100; "Output $_" } } -ThrottleLimit 5338        $job2 = Start-ThreadJob -ScriptBlock { 1..2 | ForEach-Object { Start-Sleep -Milliseconds 100; "Output $_" } }339        $job3 = Start-ThreadJob -ScriptBlock { 1..2 | ForEach-Object { Start-Sleep -Milliseconds 100; "Output $_" } }340        $job4 = Start-ThreadJob -ScriptBlock { 1..2 | ForEach-Object { Start-Sleep -Milliseconds 100; "Output $_" } }341 342        $null = $job1,$job2,$job3,$job4 | Receive-Job -Wait -AutoRemoveJob343 344        Get-Job | Where-Object PSJobTypeName -EQ "ThreadJob" | Should -HaveCount 0345    }346 347    It 'ThreadJob jobs should run in FullLanguage mode by default' {348 349        $result = Start-ThreadJob -ScriptBlock { $ExecutionContext.SessionState.LanguageMode } | Wait-Job | Receive-Job350        $result | Should -Be "FullLanguage"351    }352}353 354Describe 'Job2 class API tests' -Tags 'CI' {355 356    AfterEach {357        Get-Job | Where-Object PSJobTypeName -EQ "ThreadJob" | Remove-Job -Force358    }359 360    It 'Verifies StopJob API' {361 362        $job = Start-ThreadJob -ScriptBlock { Start-Sleep -Seconds 60 } -ThrottleLimit 5363        Wait-ForJobRunning $job364        $job.StopJob($true, "No Reason")365        $job.JobStateInfo.State | Should -Be "Stopped"366    }367 368    It 'Verifies StopJobAsync API' {369 370        $job = Start-ThreadJob -ScriptBlock { Start-Sleep -Seconds 60 } -ThrottleLimit 5371        Wait-ForJobRunning $job372        $job.StopJobAsync($true, "No Reason")373        Wait-Job $job374        $job.JobStateInfo.State | Should -Be "Stopped"375    }376 377    It 'Verifies StartJobAsync API' {378 379        $jobRunning = Start-ThreadJob -ScriptBlock { Start-Sleep -Seconds 60 } -ThrottleLimit 1380        $jobNotRunning = Start-ThreadJob -ScriptBlock { Start-Sleep -Seconds 60 }381 382        $jobNotRunning.JobStateInfo.State | Should -Be "NotStarted"383 384        # StartJobAsync starts jobs synchronously for ThreadJob jobs385        $jobNotRunning.StartJobAsync()386        Wait-ForJobRunning $jobNotRunning387        $jobNotRunning.JobStateInfo.State | Should -Be "Running"388    }389 390    It 'Verifies JobSourceAdapter Get-Jobs' {391 392        $job = Start-ThreadJob -ScriptBlock { "Hello" } | Wait-Job393 394        $getJob = Get-Job -InstanceId $job.InstanceId 2> $null395        $getJob | Should -Be $job396 397        $getJob = Get-Job -Name $job.Name 2> $null398        $getJob | Should -Be $job399 400        $getJob = Get-Job -Command ' "hello" ' 2> $null401        $getJob | Should -Be $job402 403        $getJob = Get-Job -State $job.JobStateInfo.State 2> $null404        $getJob | Should -Be $job405 406        $getJob = Get-Job -Id $job.Id 2> $null407        $getJob | Should -Be $job408 409        # Get-Job -Filter is not supported410        $result = Get-Job -Filter @{Id = ($job.Id)} 3> $null411        $result | Should -BeNullOrEmpty412    }413 414    It 'Verifies terminating job error' {415 416        $job = Start-ThreadJob -ScriptBlock { throw "My Job Error!" } | Wait-Job417        $results = $job | Receive-Job 2>&1418        $results.ToString() | Should -Be "My Job Error!"419    }420}421