Improve concurrency when running tests

PowerShell seems to have a hard time when a flood of async tasks is
  scheduled at the same time.
  I speculated that WaitForMultipleObjects() in Windows can only take up
  to 64 process handles and if you want to handle more than you should write
  some additional code which can be sub-optimal. I.e to implement Wait-Job -Any.
  I decided to test that suggestion and introduced a $Concurrency parameter with a default value of 62.
  So in the new version the script fires up up to $Concurrency value
  and wait for anything to complete before starting any more processes.
  This improved matters greatly. Individual tests against ramdrive now
  run in 8 minutes and all of the 200+ db_tests run in 9 minutes with concurrency
  values of 8-16. About 48 is required to load a CPU on my box running against HD
  but that does not improve running times much.

  Other changes include respect -EnableJE for the individual test exes.
  Enforce exclusions for the individual tests.
main
Dmitri Smirnov 9 years ago
parent c8e01ef982
commit 3277d172ba
  1. 73
      build_tools/run_ci_db_test.ps1

@ -8,7 +8,10 @@ Param(
[string]$WorkFolder = "", # Direct tests to use that folder [string]$WorkFolder = "", # Direct tests to use that folder
[int]$Limit = -1, # -1 means run all otherwise limit for testing purposes [int]$Limit = -1, # -1 means run all otherwise limit for testing purposes
[string]$Exclude = "", # Expect a comma separated list, no spaces [string]$Exclude = "", # Expect a comma separated list, no spaces
[string]$Run = "db_test" # Run db_test|tests [string]$Run = "db_test", # Run db_test|tests
# Number of async tasks that would run concurrently. Recommend a number below 64.
# However, CPU utlization really depends on the storage media. Recommend ram based disk.
[int]$Concurrency = 62
) )
# Folders and commands must be fullpath to run assuming # Folders and commands must be fullpath to run assuming
@ -122,10 +125,17 @@ function Normalize-DbTests($HashTable) {
function Discover-TestBinaries($HashTable) { function Discover-TestBinaries($HashTable) {
$Exclusions = @("db_test*", "db_sanity_test*") $Exclusions = @("db_test*", "db_sanity_test*")
$p = -join ($BinariesFolder, "*_test*.exe") if($EnableJE) {
$p = -join ($BinariesFolder, "*_test_je.exe")
} else {
$p = -join ($BinariesFolder, "*_test.exe")
}
dir -Path $p -Exclude $Exclusions | ForEach-Object { dir -Path $p -Exclude $Exclusions | ForEach-Object {
$t = ($_.Name) -replace '.exe$', '' $t = ($_.Name) -replace '.exe$', ''
if($ExcludeTests.Contains($t)) {
continue
}
$test_log = -join ($t, ".log") $test_log = -join ($t, ".log")
$HashTable.Add($t, $test_log) $HashTable.Add($t, $test_log)
} }
@ -137,6 +147,9 @@ if($Run -ceq "db_test") {
Normalize-DbTests -HashTable $TestToLog Normalize-DbTests -HashTable $TestToLog
} elseif($Run -ceq "tests") { } elseif($Run -ceq "tests") {
Discover-TestBinaries -HashTable $TestToLog Discover-TestBinaries -HashTable $TestToLog
} else {
Write-Warning "Invalid -Run option value"
exit 2
} }
@ -159,39 +172,47 @@ $JobToLog = @{}
# Test limiting factor here # Test limiting factor here
$count = 0 $count = 0
ForEach($k in $TestToLog.keys) { [bool]$success = $true;
Write-Host "Starting $k" # Wait for all to finish and get the results
$log_path = -join ($LogFolder, ($TestToLog.$k)) while(($JobToLog.Count -gt 0) -or
($TestToLog.Count -gt 0)) {
if($Run -ceq "db_test") { # Make sure we have maximum concurrent jobs running if anything
$job = Start-Job -Name $k -ScriptBlock $InvokeTestCase -ArgumentList @($db_test,$k,$log_path) # and the $Limit either not set or allows to proceed
} else { while(($JobToLog.Count -lt $Concurrency) -and
[string]$Exe = -Join ($BinariesFolder, $k) (($TestToLog.Count -gt 0) -and
$job = Start-Job -Name $k -ScriptBlock $InvokeTestAsync -ArgumentList @($exe,$log_path) (($Limit -lt 0) -or ($count -lt $Limit)))) {
}
$JobToLog.Add($job, $log_path)
# Limiting trial runs # We only need the first key
if(($Limit -gt 0) -and (++$count -ge $Limit)) { foreach($key in $TestToLog.keys) {
break $k = $key
} break
} }
[bool]$success = $true; Write-Host "Starting $k"
$log_path = -join ($LogFolder, ($TestToLog.$k))
# Wait for all to finish and get the results if($Run -ceq "db_test") {
while($JobToLog.Count -gt 0) { $job = Start-Job -Name $k -ScriptBlock $InvokeTestCase -ArgumentList @($db_test,$k,$log_path)
} else {
[string]$Exe = -Join ($BinariesFolder, $k)
$job = Start-Job -Name $k -ScriptBlock $InvokeTestAsync -ArgumentList @($exe,$log_path)
}
$jobs = @() $JobToLog.Add($job, $log_path)
foreach($k in $JobToLog.Keys) { $jobs += $k } $TestToLog.Remove($k)
<# ++$count
if(!$success) {
break
} }
#>
if($JobToLog.Count -lt 1) {
break
}
$jobs = @()
foreach($k in $JobToLog.Keys) { $jobs += $k }
$completed = Wait-Job -Job $jobs -Any $completed = Wait-Job -Job $jobs -Any
$log = $JobToLog[$completed] $log = $JobToLog[$completed]

Loading…
Cancel
Save