Added functionality to improve failure triaging (#3037)
* Added functionality to improve failure triaging - Nunit logs will be created to tests. - Logs are copied to the Azure share. - Pester is run with -Quiet - Elevated and unelevated runs for tests with appropriate tags * Copy logs to Azure share and upload to CodeCov - Zip and copy to Azure log share - Upload to codecov using cygwin * Fixed varaible name in if condition * Addressed code review comments * Modified the destination folder structure for logs - Creates a folder structure for yyyy-MM and Windows for storing logs - Updated zip file name to not have illegal characters * Modifications as suggested by codecov.io
This commit is contained in:
parent
edf685dc9c
commit
d7cf81b64d
|
@ -1,3 +1,3 @@
|
|||
# name: codecov.yml
|
||||
fixes:
|
||||
- "master/PowerShell-master::"
|
||||
- "projects/powershell-*::"
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
param(
|
||||
[Parameter(Mandatory = $true, Position = 0)] $coverallsToken
|
||||
)
|
||||
[Parameter(Mandatory = $true, Position = 0)] $coverallsToken,
|
||||
[Parameter(Mandatory = $true, Position = 1)] $codecovToken,
|
||||
[Parameter(Position = 2)] $azureLogDrive = "L:\"
|
||||
)
|
||||
|
||||
function Write-LogPassThru
|
||||
{
|
||||
|
@ -14,6 +16,30 @@ function Write-LogPassThru
|
|||
Add-Content -Path $Path -Value $Message -PassThru -Force
|
||||
}
|
||||
|
||||
function Write-BashInvokerScript
|
||||
{
|
||||
param($path)
|
||||
|
||||
$scriptContent =
|
||||
@'
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
if not exist "%~dpn0.sh" echo Script "%~dpn0.sh" not found & exit 2
|
||||
|
||||
set _CYGBIN=C:\cygwin64\bin
|
||||
if not exist "%_CYGBIN%" echo Couldn't find Cygwin at "%_CYGBIN%" & exit 3
|
||||
|
||||
:: Resolve ___.sh to /cygdrive based *nix path and store in %_CYGSCRIPT%
|
||||
for /f "delims=" %%A in ('%_CYGBIN%\cygpath.exe "%~dpn0.sh"') do set _CYGSCRIPT=%%A
|
||||
|
||||
:: Throw away temporary env vars and invoke script, passing any args that were passed to us
|
||||
endlocal & %_CYGBIN%\bash --login "%_CYGSCRIPT%" %*
|
||||
'@
|
||||
|
||||
$scriptContent | Out-File $path -Force -Encoding ascii
|
||||
}
|
||||
|
||||
Write-LogPassThru -Message "***** New Run *****"
|
||||
|
||||
$codeCoverageZip = 'https://ci.appveyor.com/api/projects/PowerShell/powershell-f975h/artifacts/CodeCoverage.zip'
|
||||
|
@ -34,6 +60,8 @@ $openCoverTargetDirectory = "$outputBaseFolder\OpenCoverToolset"
|
|||
$outputLog = "$outputBaseFolder\CodeCoverageOutput.xml"
|
||||
$psCodeZip = "$outputBaseFolder\PSCode.zip"
|
||||
$psCodePath = "$outputBaseFolder\PSCode"
|
||||
$elevatedLogs = "$outputBaseFolder\TestResults_Elevated.xml"
|
||||
$unelevatedLogs = "$outputBaseFolder\TestResults_Unelevated.xml"
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -59,23 +87,32 @@ try
|
|||
|
||||
Write-LogPassThru -Message "Expansion complete."
|
||||
|
||||
Import-Module "$openCoverPath\OpenCover"
|
||||
Import-Module "$openCoverPath\OpenCover" -Force
|
||||
Install-OpenCover -TargetDirectory $openCoverTargetDirectory -force
|
||||
Write-LogPassThru -Message "OpenCover installed."
|
||||
|
||||
Write-LogPassThru -Message "TestDirectory : $testPath"
|
||||
Write-LogPassThru -Message "openCoverPath : $openCoverTargetDirectory\OpenCover"
|
||||
Write-LogPassThru -Message "psbinpath : $psBinPath"
|
||||
Write-LogPassThru -Message "elevatedLog : $elevatedLogs"
|
||||
Write-LogPassThru -Message "unelevatedLog : $unelevatedLogs"
|
||||
|
||||
$openCoverParams = @{outputlog = $outputLog;
|
||||
TestDirectory = $testPath;
|
||||
OpenCoverPath = "$openCoverTargetDirectory\OpenCover";
|
||||
PowerShellExeDirectory = "$psBinPath\publish"
|
||||
}
|
||||
TestDirectory = $testPath;
|
||||
OpenCoverPath = "$openCoverTargetDirectory\OpenCover";
|
||||
PowerShellExeDirectory = "$psBinPath\publish";
|
||||
PesterLogElevated = $elevatedLogs;
|
||||
PesterLogUnelevated = $unelevatedLogs;
|
||||
}
|
||||
|
||||
$openCoverParams | Out-String | Write-LogPassThru
|
||||
Write-LogPassThru -Message "Starting test run."
|
||||
|
||||
if(Test-Path $outputLog)
|
||||
{
|
||||
Remove-Item $outputLog -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
Invoke-OpenCover @openCoverParams
|
||||
|
||||
if(Test-Path $outputLog)
|
||||
|
@ -99,19 +136,59 @@ try
|
|||
|
||||
$coverallsExe = Join-Path $coverallsPath "tools\csmacnz.Coveralls.exe"
|
||||
$coverallsParams = @("--opencover",
|
||||
"-i $outputLog",
|
||||
"--repoToken $coverallsToken",
|
||||
"--commitId $commitId",
|
||||
"--commitBranch master",
|
||||
"--commitAuthor `"$author`"",
|
||||
"--commitEmail $email",
|
||||
"--commitMessage `"$message`""
|
||||
)
|
||||
"-i $outputLog",
|
||||
"--repoToken $coverallsToken",
|
||||
"--commitId $commitId",
|
||||
"--commitBranch master",
|
||||
"--commitAuthor `"$author`"",
|
||||
"--commitEmail $email",
|
||||
"--commitMessage `"$message`""
|
||||
)
|
||||
|
||||
$coverallsParams | % { Write-LogPassThru -Message $_ }
|
||||
$coverallsParams | ForEach-Object { Write-LogPassThru -Message $_ }
|
||||
|
||||
Write-LogPassThru -Message "Uploading to CoverAlls"
|
||||
& $coverallsExe """$coverallsParams"""
|
||||
|
||||
$bashScriptInvoker = "$PSScriptRoot\CodecovUploader.cmd"
|
||||
$bashScript = "$PSScriptRoot\CodecovUploader.sh"
|
||||
$cygwinLocation = "$env:SystemDrive\cygwin*"
|
||||
|
||||
if($bashScript)
|
||||
{
|
||||
Remove-Item $bashScript -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
Invoke-RestMethod 'https://codecov.io/bash' -OutFile $bashScript
|
||||
Write-BashInvokerScript -path $bashScriptInvoker
|
||||
|
||||
if((Test-Path $bashScriptInvoker) -and
|
||||
(Test-Path $bashScript) -and
|
||||
(Test-Path $cygwinLocation)
|
||||
)
|
||||
{
|
||||
Write-LogPassThru -Message "Uploading to CodeCov"
|
||||
$cygwinPath = "/cygdrive/" + $outputLog.Replace("\", "/").Replace(":","")
|
||||
|
||||
$codecovParmeters = @(
|
||||
"-f $cygwinPath"
|
||||
"-X gcov",
|
||||
"-B master",
|
||||
"-C $commitId",
|
||||
"-X network")
|
||||
|
||||
$codecovParmetersString = $codecovParmeters -join ' '
|
||||
|
||||
& $bashScriptInvoker $codecovParmetersString
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-LogPassThru -Message "BashScript: $bashScript"
|
||||
Write-LogPassThru -Message "BashScriptInvoke: $bashScriptInvoker"
|
||||
Write-LogPassThru -Message "CygwinPath : $cygwinPath"
|
||||
Write-LogPassThru -Message "Cannot upload to codecov as some paths are not existent"
|
||||
}
|
||||
|
||||
Write-LogPassThru -Message "Upload complete."
|
||||
}
|
||||
catch
|
||||
|
@ -120,6 +197,20 @@ catch
|
|||
}
|
||||
finally
|
||||
{
|
||||
Remove-Item -recurse -force -path $outputBaseFolder
|
||||
## See if Azure log directory is mounted
|
||||
if(Test-Path $azureLogDrive)
|
||||
{
|
||||
##Create yyyy-dd folder
|
||||
$monthFolder = "{0:yyyy-mm}" -f [datetime]::Now
|
||||
$monthFolderFullPath = New-Item -Path (Join-Path $azureLogDrive $monthFolder) -ItemType Directory -Force
|
||||
$windowsFolderPath = New-Item (Join-Path $monthFolderFullPath "Windows") -ItemType Directory -Force
|
||||
|
||||
$destinationPath = Join-Path $env:Temp ("CodeCoverageLogs-{0:yyyy_MM_dd}-{0:hh_mm_ss}.zip" -f [datetime]::Now)
|
||||
Compress-Archive -Path $elevatedLogs,$unelevatedLogs,$outputLog -DestinationPath $destinationPath
|
||||
Copy-Item $destinationPath $windowsFolderPath -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
## Disable the cleanup till we stabilize.
|
||||
#Remove-Item -recurse -force -path $outputBaseFolder
|
||||
$ErrorActionPreference = $oldErrorActionPreference
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@ function Get-CodeCoverageChange($r1, $r2)
|
|||
$h = @{}
|
||||
$Deltas = new-object "System.Collections.ArrayList"
|
||||
|
||||
$r1.assembly | % { $h[$_.assemblyname] = @($_) }
|
||||
$r2.assembly | % {
|
||||
$r1.assembly | ForEach-Object { $h[$_.assemblyname] = @($_) }
|
||||
$r2.assembly | ForEach-Object {
|
||||
if($h.ContainsKey($_.assemblyname))
|
||||
{
|
||||
$h[$_.assemblyname] += $_
|
||||
|
@ -91,7 +91,7 @@ function Get-CoverageData($xmlPath)
|
|||
|
||||
$assemblies = New-Object System.Collections.ArrayList
|
||||
|
||||
foreach( $module in $CoverageXml.CoverageSession.modules.module|?{$_.skippedDueTo -ne "MissingPdb"}) {
|
||||
foreach( $module in $CoverageXml.CoverageSession.modules.module| Where-Object {$_.skippedDueTo -ne "MissingPdb"}) {
|
||||
$assemblies.Add((Get-AssemblyCoverageData -element $module)) | Out-Null
|
||||
}
|
||||
|
||||
|
@ -380,6 +380,9 @@ function Invoke-OpenCover
|
|||
[parameter()]$TestDirectory = "$($script:psRepoPath)/test/powershell",
|
||||
[parameter()]$OpenCoverPath = "~/OpenCover",
|
||||
[parameter()]$PowerShellExeDirectory = "$($script:psRepoPath)/src/powershell-win-core/bin/CodeCoverage/netcoreapp1.0/win10-x64",
|
||||
[parameter()]$PesterLogElevated = "$pwd/TestResultsElevated.xml",
|
||||
[parameter()]$PesterLogUnelevated = "$pwd/TestResultsUnelevated.xml",
|
||||
[parameter()]$PesterLogFormat = "NUnitXml",
|
||||
[switch]$CIOnly
|
||||
)
|
||||
|
||||
|
@ -408,14 +411,26 @@ function Invoke-OpenCover
|
|||
|
||||
if ( $CIOnly )
|
||||
{
|
||||
$targetArgs += "-excludeTag @('Feature','Scenario','Slow','RequireAdminOnWindows')"
|
||||
$targetArgsElevated = $targetArgs + @("-excludeTag @('Feature','Scenario','Slow')", "-Tag @('RequireAdminOnWindows')")
|
||||
$targetArgsUnelevated = $targetArgs + @("-excludeTag @('Feature','Scenario','Slow','RequireAdminOnWindows')")
|
||||
}
|
||||
else
|
||||
{
|
||||
$targetArgsElevated = $targetArgs + @("-Tag @('RequireAdminOnWindows')")
|
||||
$targetArgsUnelevated = $targetArgs + @("-excludeTag @('RequireAdminOnWindows')")
|
||||
}
|
||||
|
||||
$targetArgString = $targetArgs -join " "
|
||||
# the order seems to be important. Always keep -targetargs as the last parameter.
|
||||
$openCoverArgs = "-target:$target","-register:user","-output:${outputLog}","-nodefaultfilters","-oldstyle","-hideskipped:all","-targetargs:`"$targetArgString`""
|
||||
$targetArgsElevated += @("-OutputFile $PesterLogElevated", "-OutputFormat $PesterLogFormat", "-Quiet")
|
||||
$targetArgsUnelevated += @("-OutputFile $PesterLogUnelevated", "-OutputFormat $PesterLogFormat", "-Quiet")
|
||||
|
||||
if ( $PSCmdlet.ShouldProcess("$OpenCoverBin $openCoverArgs") )
|
||||
$targetArgStringElevated = $targetArgsElevated -join " "
|
||||
$targetArgStringUnelevated = $targetArgsUnelevated -join " "
|
||||
# the order seems to be important. Always keep -targetargs as the last parameter.
|
||||
$openCoverArgsElevated = "-target:$target","-register:user","-output:${outputLog}","-nodefaultfilters","-oldstyle","-hideskipped:all","-mergebyhash","-targetargs:`"$targetArgStringElevated`""
|
||||
$openCoverArgsUnelevated = "-target:$target","-register:user","-output:${outputLog}","-nodefaultfilters","-oldstyle","-hideskipped:all", "-mergebyhash", "-targetargs:`"$targetArgStringUnelevated`""
|
||||
$openCoverArgsUnelevatedString = $openCoverArgsUnelevated -join " "
|
||||
|
||||
if ( $PSCmdlet.ShouldProcess("$OpenCoverBin $openCoverArgsUnelevated") )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -428,13 +443,34 @@ function Invoke-OpenCover
|
|||
throw "${env:psmodulepath} does not exist"
|
||||
}
|
||||
|
||||
# invoke OpenCover
|
||||
& $OpenCoverBin $openCoverArgs
|
||||
# invoke OpenCover elevated
|
||||
& $OpenCoverBin $openCoverArgsElevated
|
||||
|
||||
# invoke OpenCover unelevated and poll for completion
|
||||
"$openCoverBin $openCoverArgsUnelevatedString" | Out-File -FilePath "$env:temp\unelevated.ps1" -Force
|
||||
runas.exe /trustlevel:0x20000 "powershell.exe -file $env:temp\unelevated.ps1"
|
||||
# wait for process to start
|
||||
Start-Sleep -Seconds 5
|
||||
# poll for process exit every 30 seconds
|
||||
# timeout of 3 hours
|
||||
$timeOut = ([datetime]::Now).AddHours(3)
|
||||
while([datetime]::Now -lt $timeOut)
|
||||
{
|
||||
Start-Sleep -Seconds 30
|
||||
$openCoverProcess = Get-Process "OpenCover.Console" -ErrorAction SilentlyContinue
|
||||
|
||||
if(-not $openCoverProcess)
|
||||
{
|
||||
#run must have completed.
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
# set it back
|
||||
$env:PSModulePath = $saveModPath
|
||||
Remove-Item "$env:temp\unelevated.ps1" -force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue