diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-ChildItem.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-ChildItem.Tests.ps1 index d3964dc8dc1..b9d6ccb1c9f 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-ChildItem.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-ChildItem.Tests.ps1 @@ -60,11 +60,11 @@ Describe "Get-ChildItem" -Tags "CI" { $files.Count | Should be 1 $files[0].Name | Should Be $item_F } - It "Should give .sys file if the fullpath is specified with hidden and force parameter" -Skip:(!$IsWindows){ - $file = Get-ChildItem -path "$env:SystemDrive\\pagefile.sys" -Hidden - $file | Should not be $null + It "Should find the hidden file if specified with hidden switch" { + $file = Get-ChildItem -Path (Join-Path $TestDrive $item_F) -Hidden + $file | Should Not BeNullOrEmpty $file.Count | Should be 1 - $file.Name | Should be "pagefile.sys" + $file.Name | Should be $item_F } It "Should continue enumerating a directory when a contained item is deleted" { $Error.Clear() diff --git a/test/tools/CodeCoverageAutomation/Start-CodeCoverageRun.ps1 b/test/tools/CodeCoverageAutomation/Start-CodeCoverageRun.ps1 index cb259c267ff..9c3f24722f1 100644 --- a/test/tools/CodeCoverageAutomation/Start-CodeCoverageRun.ps1 +++ b/test/tools/CodeCoverageAutomation/Start-CodeCoverageRun.ps1 @@ -4,6 +4,81 @@ [Parameter(Position = 2)] $azureLogDrive = "L:\" ) +# Read the XML and create a dictionary for FileUID -> file full path. +function GetFileTable() +{ + $files = $script:covData | Select-Xml './/File' + foreach($file in $files) + { + $script:fileTable[$file.Node.uid] = $file.Node.fullPath + } +} + +# Get sequence points for a particular file +function GetSequencePointsForFile([string] $fileId) +{ + $lineCoverage = [System.Collections.Generic.Dictionary[string,int]]::new() + + $sequencePoints = $script:covData | Select-Xml ".//SequencePoint[@fileid = '$fileId']" + + if($sequencePoints.Count -gt 0) + { + foreach($sp in $sequencePoints) + { + $visitedCount = [int]::Parse($sp.Node.vc) + $lineNumber = [int]::Parse($sp.Node.sl) + $lineCoverage[$lineNumber] += [int]::Parse($visitedCount) + } + + return $lineCoverage + } +} + +#### Convert the OpenCover XML output for CodeCov.io JSON format as it is smaller. +function ConvertTo-CodeCovJson +{ + param( + [string] $Path, + [string] $DestinationPath + ) + + $Script:fileTable = [ordered]@{} + $Script:covData = [xml] (Get-Content -ReadCount 0 -Raw -Path $Path) + $totalCoverage = [PSCustomObject]::new() + $totalCoverage | Add-Member -MemberType NoteProperty -Name "coverage" -Value ([PSCustomObject]::new()) + + ## Populate the dictionary with file uid and file names. + GetFileTable + $keys = $Script:fileTable.Keys + $progress=0 + foreach($f in $keys) + { + Write-Progress -Id 1 -Activity "Converting to JSON" -Status 'Converting' -PercentComplete ($progress * 100 / $keys.Count) + $fileCoverage = GetSequencePointsForFile -fileId $f + $fileName = $Script:fileTable[$f] + $previousFileCoverage = $totalCoverage.coverage.${fileName} + + ##Update the values for the lines in the file. + if($previousFileCoverage -ne $null) + { + foreach($lineNumber in $fileCoverage.Keys) + { + $previousFileCoverage[$lineNumber] += [int]::Parse($fileCoverage[$lineNumber]) + } + } + else ## the file is new, so add the values as a new NoteProperty. + { + $totalCoverage.coverage | Add-Member -MemberType NoteProperty -Value $fileCoverage -Name $fileName + } + + $progress++ + } + + Write-Progress -Id 1 -Completed -Activity "Converting to JSON" + + $totalCoverage | ConvertTo-Json -Depth 5 -Compress | out-file $DestinationPath -Encoding ascii +} + function Write-LogPassThru { Param( @@ -28,19 +103,9 @@ function Push-CodeCovData $url="https://codecov.io" $query = "package=bash-${VERSION}&token=${token}&branch=${Branch}&commit=${CommitID}&build=&build_url=&tag=&slug=&yaml=&service=&flags=&pr=&job=" + $uri = "$url/upload/v2?${query}" + $response = Invoke-WebRequest -Method Post -InFile $file -Uri $uri - $CodeCovHeader = @{ Accept = "text/plain" } - $uri = "$url/upload/v4?${query}" - $response = Invoke-WebRequest -Method POST -Uri $uri -Headers $CodeCovHeader - if ( $response.StatusCode -ne 200 ) - { - Write-LogPassThru -Message "Could not get upload url for request $uri" - throw "Could not get upload url" - } - $uploaduri = $response.content.split("`n")[-1] - - $UploadHeader = @{ "Content-Type" = "text/plain"; "x-amz-acl" = "public-read"; "x-amz-storage-class" = "REDUCED_REDUNDANCY" } - $response = Invoke-WebRequest -Method Put -Uri $uploaduri -InFile $file -Headers $UploadHeader if ( $response.StatusCode -ne 200 ) { Write-LogPassThru -Message "Upload failed for upload uri: $uploaduri" @@ -65,15 +130,15 @@ $outputBaseFolder = "$env:Temp\CC" $null = New-Item -ItemType Directory -Path $outputBaseFolder -Force $openCoverPath = "$outputBaseFolder\OpenCover" -$testPath = "$outputBaseFolder\tests" +$testRootPath = "$outputBaseFolder\tests" +$testPath = "$testRootPath\powershell" $psBinPath = "$outputBaseFolder\PSCodeCoverage" $openCoverTargetDirectory = "$outputBaseFolder\OpenCoverToolset" $outputLog = "$outputBaseFolder\CodeCoverageOutput.xml" -$psCodeZip = "$outputBaseFolder\PSCode.zip" -$psCodePath = "$outputBaseFolder\PSCode" $elevatedLogs = "$outputBaseFolder\TestResults_Elevated.xml" $unelevatedLogs = "$outputBaseFolder\TestResults_Unelevated.xml" -$testToolsPath = "$testPath\tools" +$testToolsPath = "$testRootPath\tools" +$jsonFile = "$outputBaseFolder\CC.json" try { @@ -86,7 +151,7 @@ try Write-LogPassThru -Message "Downloads complete. Starting expansion" Expand-Archive -path "$outputBaseFolder\PSCodeCoverage.zip" -destinationpath "$psBinPath" -Force - Expand-Archive -path "$outputBaseFolder\tests.zip" -destinationpath $testPath -Force + Expand-Archive -path "$outputBaseFolder\tests.zip" -destinationpath $testRootPath -Force Expand-Archive -path "$outputBaseFolder\OpenCover.zip" -destinationpath $openCoverPath -Force ## Download Coveralls.net uploader @@ -165,7 +230,8 @@ try & $coverallsExe """$coverallsParams""" Write-LogPassThru -Message "Uploading to CodeCov" - Push-CodeCovData -file $outputLog -CommitID $commitId -token $codecovToken -Branch 'master' + ConvertTo-CodeCovJson -Path $outputLog -DestinationPath $jsonFile + Push-CodeCovData -file $jsonFile -CommitID $commitId -token $codecovToken -Branch 'master' Write-LogPassThru -Message "Upload complete." } @@ -192,5 +258,9 @@ finally ## Disable the cleanup till we stabilize. #Remove-Item -recurse -force -path $outputBaseFolder + + ## This is required so we do not keep on merging coverage reports. + Remove-Item $outputLog -Force -ErrorAction SilentlyContinue + $ErrorActionPreference = $oldErrorActionPreference } diff --git a/test/tools/OpenCover/OpenCover.psm1 b/test/tools/OpenCover/OpenCover.psm1 index adf03f7e73f..4e167126763 100644 --- a/test/tools/OpenCover/OpenCover.psm1 +++ b/test/tools/OpenCover/OpenCover.psm1 @@ -433,6 +433,16 @@ function Invoke-OpenCover [switch]$CIOnly ) + # check for elevation + $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() + $principal = New-Object System.Security.Principal.WindowsPrincipal($identity) + $isElevated = $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator) + + if(-not $isElevated) + { + throw 'Please run from an elevated PowerShell.' + } + # check to be sure that OpenCover is present $OpenCoverBin = "$OpenCoverPath\opencover.console.exe" @@ -455,7 +465,7 @@ function Invoke-OpenCover # create the arguments for OpenCover - $startupArgs = '$env:PSModulePath = "${env:PSModulePath};$TestToolsPath";Set-ExecutionPolicy Bypass -Force -Scope Process;' + $startupArgs = 'Set-ExecutionPolicy Bypass -Force -Scope Process;' $targetArgs = "-c","${startupArgs}", "Invoke-Pester","${TestDirectory}" if ( $CIOnly ) @@ -486,10 +496,16 @@ function Invoke-OpenCover # check to be sure that the module path is present # this isn't done earlier because there's no need to change env:PSModulePath unless we're going to really run tests $saveModPath = $env:PSModulePath - $env:PSModulePath = "${PowerShellExeDirectory}\Modules" - if ( ! (test-path $env:PSModulePath) ) + $env:PSModulePath = "${PowerShellExeDirectory}\Modules;$TestToolsModulesPath" + + $modulePathParts = $env:PSModulePath -split ';' + + foreach($part in $modulePathParts) { - throw "${env:PSModulePath} does not exist" + if ( ! (test-path $part) ) + { + throw "${part} does not exist" + } } # invoke OpenCover elevated @@ -500,12 +516,12 @@ function Invoke-OpenCover 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) + # poll for process exit every 60 seconds + # timeout of 6 hours + $timeOut = ([datetime]::Now).AddHours(6) while([datetime]::Now -lt $timeOut) { - Start-Sleep -Seconds 30 + Start-Sleep -Seconds 60 $openCoverProcess = Get-Process "OpenCover.Console" -ErrorAction SilentlyContinue if(-not $openCoverProcess)