diff --git a/codecov.yml b/codecov.yml index d0bde89357..92aa7280b0 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,3 +1,3 @@ # name: codecov.yml fixes: - - "master/PowerShell-master::" + - "projects/powershell-*::" diff --git a/test/tools/CodeCoverageAutomation/Start-CodeCoverageRun.ps1 b/test/tools/CodeCoverageAutomation/Start-CodeCoverageRun.ps1 index 8e36c3ea6e..9ba4a16716 100644 --- a/test/tools/CodeCoverageAutomation/Start-CodeCoverageRun.ps1 +++ b/test/tools/CodeCoverageAutomation/Start-CodeCoverageRun.ps1 @@ -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 -} \ No newline at end of file +} diff --git a/test/tools/OpenCover/OpenCover.psm1 b/test/tools/OpenCover/OpenCover.psm1 index 83d3536c7d..a7224f49f2 100644 --- a/test/tools/OpenCover/OpenCover.psm1 +++ b/test/tools/OpenCover/OpenCover.psm1 @@ -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 } } } \ No newline at end of file