<# .SYNOPSIS Run regression test on Windows. .DESCRIPTION Build test programs and run them. .PARAMETER Target Specify the target of MSBuild. "Build&Go"(default), "Build" or "Clean" is available. .PARAMETER TestList Specify the list of test cases. If this parameter isn't specified(default), all test cases are executed. .PARAMETER Ansi Specify this switch in case of testing Ansi drivers. .PARAMETER DeclareFetch Specify Use Declare/Fetch mode. "On"(default), "off" or "both" is available. .PARAMETER DsnInfo Specify the dsn info "SERVER=${server}|DATABASE=${database}|PORT=${port}|UID=${uid}|PWD=${passwd}" .PARAMETER VCVersion Used Visual Studio version is determined automatically unless this option is specified. .PARAMETER Platform Specify platforms to test. "x64"(default), "Win32" or "both" is available. .PARAMETER Toolset MSBuild PlatformToolset is determined automatically unless this option is specified. Currently "v100", "Windows7.1SDK", "v110", "v110_xp", "v120", "v120_xp", "v140" or "v140_xp" is available. .PARAMETER MSToolsVersion This option is deprecated. MSBuild ToolsVersion is determined automatically unless this option is specified. Currently "4.0", "12.0" or "14.0" is available. .PARAMETER Configuration Specify the configuration used to build executables for the regression tests. "Release"(default) or "Debug". .PARAMETER DriverConfiguration Specify the configuration which was used to build the driver dlls to test. "Release"(default) or "Debug". .PARAMETER BuildConfigPath Specify the configuration xml file name if you want to use the configuration file other than standard one. The relative path is relative to the current directory. .PARAMETER ReinstallDriver Reinstall the driver in any case. .PARAMETER ExpectMimalloc Specify whether usage of the mimalloc allocator is expected. .EXAMPLE > .\regress Build with default or automatically selected parameters and run tests. .EXAMPLE > .\regress Clean Clean all generated files. .EXAMPLE > .\regress -TestList connect, deprecated Build and run connect-test and deprecated-test. .EXAMPLE > .\regress -Ansi Build and run with ANSI version of drivers. .EXAMPLE > .\regress -V(CVersion) 14.0 Build using Visual Studio 14.0 environment and run tests. .EXAMPLE > .\regress -P(latform) x64 Build 64bit test programs and run them. .NOTES Author: Hiroshi Inoue Date: August 2, 2016 #> # # build 32bit & 64bit dlls for VC10 or later # Param( [ValidateSet("Build&Go", "Build", "Clean")] [string]$Target="Build&Go", [string[]]$TestList, [switch]$Ansi, [string]$VCVersion, [ValidateSet("Win32", "x64", "both")] [string]$Platform="both", [string]$Toolset, [ValidateSet("", "4.0", "12.0", "14.0")] [string]$MSToolsVersion, [ValidateSet("Debug", "Release")] [String]$Configuration="Release", [ValidateSet("Debug", "Release")] [String]$DriverConfiguration="Release", [string]$BuildConfigPath, [ValidateSet("off", "on", "both")] [string]$DeclareFetch="on", [string]$DsnInfo, [string]$SpecificDsn, [switch]$ReinstallDriver, [switch]$ExpectMimalloc ) function testlist_make($testsf) { $testbins=@() $testnames=@() $dirnames=@() $testexes=@() $f = (Get-Content -Path $testsf) -as [string[]] $nstart=$false foreach ($l in $f) { if ($l[0] -eq "#") { continue } $sary=-split $l if ($sary[0] -eq "#") { continue } if ($sary[0] -eq "TESTBINS") { $nstart=$true $sary[0]=$null if ($sary[1] -eq "=") { $sary[1]=$null } } if ($nstart) { if ($sary[$sary.length - 1] -eq "\") { $sary[$sary.length - 1] = $null } else { $nstart=$false } $testbins+=$sary if (-not $nstart) { break } } } for ($i=0; $i -lt $testbins.length; $i++) { Write-Debug "$i : $testbins[$i]" } foreach ($testbin in $testbins) { if ("$testbin" -eq "") { continue } $sary=$testbin.split("/") $testname=$sary[$sary.length -1] $dirname="" for ($i=0;$i -lt $sary.length - 1;$i++) { $dirname+=($sary[$i]+"`\") } Write-Debug "testbin=$testbin => testname=$testname dirname=$dirname" $dirnames += $dirname $testexes+=($dirname+$testname+".exe") $testnames+=$testname.Replace("-test","") } return $testexes, $testnames, $dirnames } function vcxfile_make($testnames, $dirnames, $vcxfile) { # here-string @' . Release $(scriptPath)\..\test\src\ '@ > $vcxfile for ($i=0; $i -lt $testnames.length; $i++) { $testname=$testnames[$i] $dirname=$dirnames[$i] $testname+="-test" # here-string @" "@ >> $vcxfile } # here-string @' '@ >> $vcxfile } function RunTest($scriptPath, $Platform, $testexes) { $originalErrorActionPreference = $ErrorActionPreference # Run regression tests if ($Platform -eq "x64") { $targetdir="test_x64" } else { $targetdir="test_x86" } $revsdir=$scriptPath $origdir="${revsdir}\..\test" try { $regdiff="regression.diffs" $RESDIR="results" if (Test-Path $regdiff) { Remove-Item $regdiff } New-Item $RESDIR -ItemType Directory -Force > $null Get-Content "${origdir}\sampletables.sql" | .\reset-db if ($LASTEXITCODE -ne 0) { throw "`treset_db error" } $cnstr = @() switch ($DeclareFetch) { "off" { $cnstr += "UseDeclareFetch=0" } "on" { $cnstr += "UseDeclareFetch=1" } "both" { $cnstr += "UseDeclareFetch=0" $cnstr += "UseDeclareFetch=1" } } if ($cnstr.length -eq 0) { $cnstr += $null } # Temporarily set $ErrorActionPreference to "Continue" because MIMALLOC_VERBOSE writes to stderr $ErrorActionPreference = "Continue" $env:MIMALLOC_VERBOSE = 1 for ($i = 0; $i -lt $cnstr.length; $i++) { $env:COMMON_CONNECTION_STRING_FOR_REGRESSION_TEST = $cnstr[$i] if ("$SpecificDsn" -ne "") { $env:COMMON_CONNECTION_STRING_FOR_REGRESSION_TEST += ";Database=contrib_regression;ConnSettings={set lc_messages='C'}" } write-host "`n`tSetting by env variable:$env:COMMON_CONNECTION_STRING_FOR_REGRESSION_TEST" .\runsuite $testexes --inputdir=$origdir 2>&1 | Tee-Object -Variable runsuiteOutput # Check whether mimalloc ran by searching for a verbose message from mimalloc if ($ExpectMimalloc -xor ($runsuiteOutput -match "mimalloc: process done")) { throw "`tmimalloc usage was expected to be $ExpectMimalloc" } } } catch [Exception] { throw $error[0] } finally { $env:COMMON_CONNECTION_STRING_FOR_REGRESSION_TEST = $null $env:MIMALLOC_VERBOSE = $null $ErrorActionPreference = $originalErrorActionPreference } } function SpecialDsn($testdsn, $testdriver, $dsninfo) { function input-dsninfo($server="localhost", $uid="postgres", $passwd="postgres", $port="5432", $database="contrib_regression") { $in = read-host "Server [$server]" if ("$in" -ne "") { $server = $in } $in = read-host "Port [$port]" if ("$in" -ne "") { $port = $in } $in = read-host "Username [$uid]" if ("$in" -ne "") { $uid = $in } $in = read-host -assecurestring "Password [$passwd]" if ($in.Length -ne 0) { $ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($in) $passwd = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ptr) } return "SERVER=${server}|DATABASE=${database}|PORT=${port}|UID=${uid}|PWD=${passwd}" } $reinst = $ReinstallDriver $regProgram = "./RegisterRegdsn.exe" & $regProgram "check_dsn" $testdsn switch ($LastExitCode) { -1 { Write-Host "`tAdding System DSN=$testdsn Driver=$testdriver" if ($dsninfo.Length -eq 0) { $prop = input-dsninfo } else { $prop = $dsninfo } $prop += "|Debug=0|Commlog=0|ConnSettings=set+lc_messages='C'" $proc = Start-Process $regProgram -Verb runas -Wait -PassThru -ArgumentList "register_dsn $testdriver $testdsn $prop `"$dlldir`" Driver=${dllname}|Setup=${setup}" if ($proc.ExitCode -ne 0) { throw "`tAddDsn $testdsn error" } } -2 { $reinst = $true <# Write-Host "`tReinstalling Driver=$testdriver" $proc = Start-Process $regProgram -Verb runas -Wait -PassThru -ArgumentList "reinstall_driver $testdriver `"$dlldir`" Driver=${dllname}|Setup=${setup}" #> } 0 {} default { throw "$regProgram error" } } if ($reinst) { Write-Host "`tReinstalling Driver=$testdriver" $proc = Start-Process $regProgram -Verb runas -Wait -PassThru -ArgumentList "reinstall_driver $testdriver `"$dlldir`" Driver=${dllname}|Setup=${setup}" } } $scriptPath = (Split-Path $MyInvocation.MyCommand.Path) $usingExe=$true $testsf="$scriptPath\..\test\tests" Write-Debug testsf=$testsf $arrays=testlist_make $testsf if ($null -eq $TestList) { $TESTEXES=$arrays[0] $TESTNAMES=$arrays[1] $DIRNAMES=$arrays[2] } else { $err=$false $TESTNAMES=$TestList $TESTEXES=@() $DIRNAMES=@() foreach ($l in $TestList) { for ($i=0;$i -lt $arrays[1].length;$i++) { if ($l -eq $arrays[1][$i]) { $TESTEXES+=$arrays[0][$i] $DIRNAMES+=$arrays[2][$i] break } } <# if ($i -ge $arrays[1].length) { Write-Host "!! test case $l doesn't exist" $err=$true } #> } if ($err) { return } } Import-Module "$scriptPath\Psqlodbc-config.psm1" $configInfo = LoadConfiguration $BuildConfigPath $scriptPath $objbase = GetObjbase "$scriptPath\.." $pushdir = GetObjbase "$scriptPath" Import-Module ${scriptPath}\MSProgram-Get.psm1 $rtnArray=Find-MSBuild ([ref]$VCVersion) ($MSToolsVersion) ([ref]$Toolset) $configInfo $msbuildexe=$rtnArray[0] $MSToolsV=$rtnArray[1] write-host "vcversion=$VCVersion toolset=$Toolset" Remove-Module MSProgram-Get Remove-Module Psqlodbc-config $vcxfile="$objbase\generated_regress.vcxproj" vcxfile_make $TESTNAMES $DIRNAMES $vcxfile if ($Platform -ieq "both") { $pary = @("Win32", "x64") } else { $pary = @($Platform) } $vcx_target=$target if ($target -ieq "Build&Go") { $vcx_target="Build" } if ($Ansi) { write-host ** testing Ansi driver ** $testdriver="postgres_deva" $testdsn="psqlodbc_test_dsn_ansi" $ansi_dir_part="ANSI" $dllname="psqlsetupa.dll" $setup="psqlsetupa.dll" } else { write-host ** testing unicode driver ** $testdriver="postgres_devw" $testdsn="psqlodbc_test_dsn" $ansi_dir_part="Unicode" $dllname="psqlsetup.dll" $setup="psqlsetup.dll" } if ($DriverConfiguration -ieq "Debug") { $testdriver += "_debug" $testdsn += "_debug" } if ("$DsnInfo" -ne "") { Write-Host "`tDsn Info=$DsnInfo" $dsninfo=$DsnInfo } if ("$SpecificDsn" -ne "") { Write-Host "`tSpecific DSN=$SpecificDsn" $testdsn=$SpecificDsn } foreach ($pl in $pary) { cd $scriptPath & ${msbuildexe} ${vcxfile} /tv:$MSToolsV "/p:Platform=$pl;Configuration=$Configuration;PlatformToolset=${Toolset}" /t:$vcx_target /p:VisualStudioVersion=${VCVersion} /p:scriptPath=${scriptPath} /Verbosity:minimal if ($LASTEXITCODE -ne 0) { throw "`nCompile error" } if (($target -ieq "Clean") -or ($target -ieq "Build")) { continue } switch ($pl) { "Win32" { $targetdir="test_x86" $bit="32-bit" $dlldir="$objbase\x86_${ansi_dir_part}_$DriverConfiguration" } default { $targetdir="test_x64" $bit="64-bit" $dlldir="$objbase\x64_${ansi_dir_part}_$DriverConfiguration" } } pushd $pushdir\$targetdir $env:PSQLODBC_TEST_DSN = $testdsn try { SpecialDsn $testdsn $testdriver $dsninfo RunTest $scriptPath $pl $TESTEXES } catch [Exception] { throw $error[0] } finally { popd $env:PSQLODBC_TEST_DSN = $null } }