PowerShell/test/common/markdown/markdown-link.tests.ps1
xtqqczze b03b968d0a
Restore markdownlint tests (#12549)
Co-authored-by: Travis Plunk <travis.plunk@microsoft.com>
2020-06-02 12:28:32 -07:00

145 lines
5.2 KiB
PowerShell

# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
Describe "Verify Markdown Links" {
BeforeAll {
if(!(Get-Command -Name 'markdown-link-check' -ErrorAction SilentlyContinue))
{
Write-Verbose "installing markdown-link-check ..." -Verbose
start-nativeExecution {
sudo yarn global add markdown-link-check@3.7.2
}
}
if(!(Get-Module -Name 'ThreadJob' -ListAvailable -ErrorAction SilentlyContinue))
{
Install-Module -Name ThreadJob -Scope CurrentUser
}
# Cleanup jobs for reliability
Get-Job | Remove-Job -Force
}
AfterAll {
# Cleanup jobs to leave the process the same
Get-Job | Remove-Job -Force
}
$groups = Get-ChildItem -Path "$PSScriptRoot\..\..\..\*.md" -Recurse | Where-Object {$_.DirectoryName -notlike '*node_modules*'} | Group-Object -Property directory
$jobs = @{}
# start all link verification in parallel
Foreach($group in $groups)
{
Write-Verbose -Verbose "starting jobs for $($group.Name) ..."
$job = Start-ThreadJob {
param([object] $group)
foreach($file in $group.Group)
{
$results = markdown-link-check $file 2>&1
Write-Output ([PSCustomObject]@{
file = $file
results = $results
})
}
} -ArgumentList @($group)
$jobs.add($group.name,$job)
}
Write-Verbose -Verbose "Getting results ..."
# Get the results and verify
foreach($key in $jobs.keys)
{
$job = $jobs.$key
$results = Receive-Job -Job $job -Wait
Remove-Job -Job $Job
foreach($jobResult in $results)
{
$file = $jobResult.file
$result = $jobResult.results
Context "Verify links in $file" {
# failures look like `[✖] https://someurl` (perhaps without the https://)
# passes look like `[✓] https://someurl` (perhaps without the https://)
$failures = $result -like '*[✖]*' | ForEach-Object { $_.Substring(4).Trim() }
$passes = $result -like '*[✓]*' | ForEach-Object {
@{url=$_.Substring(4).Trim() }
}
$trueFailures = @()
$verifyFailures = @()
foreach ($failure in $failures) {
if($failure -like 'https://www.amazon.com*')
{
# In testing amazon links often failed when they are valid
# Verify manually
$verifyFailures += @{url = $failure}
}
else
{
$trueFailures += @{url = $failure}
}
}
# must have some code in the test for it to pass
function noop {
}
if($passes)
{
It "<url> should work" -TestCases $passes {
noop
}
}
if($trueFailures)
{
It "<url> should work" -TestCases $trueFailures {
param($url)
# there could be multiple reasons why a failure is ok
# check against the allowed failures
$allowedFailures = [System.Net.HttpStatusCode[]](
503, # Service Unavailable
504 # Gateway Timeout
)
$prefix = $url.Substring(0,7)
# Logging for diagnosability. Azure DevOps sometimes redacts the full url.
Write-Verbose "prefix: '$prefix'"
if($url -match '^http(s)?:')
{
# If invoke-WebRequest can handle the URL, re-verify, with 6 retries
try
{
$null = Invoke-WebRequest -Uri $url -RetryIntervalSec 10 -MaximumRetryCount 6
}
catch [Microsoft.PowerShell.Commands.HttpResponseException]
{
if ( $allowedFailures -notcontains $_.Exception.Response.StatusCode ) {
throw "Failed to complete request to `"$url`". $($_.Exception.Message)"
}
}
}
else {
throw "Tool reported URL as unreachable."
}
}
}
if($verifyFailures)
{
It "<url> should work" -TestCases $verifyFailures -Pending {
}
}
if(!$passes -and !$trueFailures -and !$verifyFailures)
{
It "has no links" {
noop
}
}
}
}
}
}