eng/scripts/MgmtTestLib.ps1 (353 lines of code) (raw):
#Requires -Version 7.0
$MOCK_SERVER_NAME = "mock-server"
$MOCK_SERVER_DIR = "mock-service-host"
$MOCK_SERVER_READY = "validator initialized"
$MOCK_SERVER_WAIT_TIME = 600
function Invoke-MgmtTestgen ()
{
param (
[string]$sdkDirectory = "",
[switch]$clean,
[switch]$vet,
[switch]$generateExample,
[switch]$generateMockTest,
[switch]$skipBuild,
[switch]$cleanGenerated,
[switch]$format,
[switch]$tidy,
[switch]$factoryGatherCommonParams,
[string]$autorestPath = "",
[string]$config = "autorest.md",
[string]$goExtension = "@autorest/go@4.0.0-preview.72",
[string]$testExtension = "@autorest/gotest@4.7.4",
[string]$outputFolder
)
if ($clean)
{
Write-Host "##[command]Executing go clean -v ./... in " $sdkDirectory
go clean -v ./...
if ($LASTEXITCODE) { exit $LASTEXITCODE }
}
if ($cleanGenerated)
{
Write-Host "##[command]Cleaning auto-generated files in" $sdkDirectory
(Get-ChildItem "*_test.go" | Select-String -Pattern "Code generated by Microsoft" | Select-Object -ExpandProperty path) | Remove-Item -Force
}
if ($generateExample -or $generateMockTest)
{
Write-Host "##[command]Executing autorest.gotest in " $sdkDirectory
if ($autorestPath -eq "")
{
$autorestPath = "./" + $config
}
if ($outputFolder -eq '')
{
$outputFolder = $sdkDirectory
}
$exampleFlag = "false"
if ($generateExample)
{
$exampleFlag = "true"
}
$mockTestFlag = "true"
if (-not $generateMockTest)
{
$mockTestFlag = "false"
}
$factoryGatherAllParamsFlag = "true"
if ($factoryGatherCommonParams)
{
$factoryGatherAllParamsFlag = "false"
}
$honorBodyPlacement = "true"
if (Get-ChildItem "build.go" | Select-String -Pattern "alwaysSetBodyParamRequired")
{
$honorBodyPlacement = "false"
}
$removeUnreferencedTypesFlag = "false"
if (Get-ChildItem "build.go" | Select-String -Pattern "removeUnreferencedTypes")
{
$removeUnreferencedTypesFlag = "true"
}
Write-Host "autorest --use=$goExtension --use=$testExtension --go --track2 --output-folder=$outputFolder --clear-output-folder=false --go.clear-output-folder=false --generate-sdk=false --testmodeler.generate-mock-test=$mockTestFlag --testmodeler.generate-sdk-example=$exampleFlag --honor-body-placement=$honorBodyPlacement --remove-unreferenced-types=$removeUnreferencedTypesFlag --factory-gather-all-params=$factoryGatherAllParamsFlag $autorestPath"
npx autorest --use=$goExtension --use=$testExtension --go --track2 --output-folder=$outputFolder --clear-output-folder=false --go.clear-output-folder=false --generate-sdk=false --testmodeler.generate-mock-test=$mockTestFlag --testmodeler.generate-sdk-example=$exampleFlag --honor-body-placement=$honorBodyPlacement --remove-unreferenced-types=$removeUnreferencedTypesFlag --factory-gather-all-params=$factoryGatherAllParamsFlag $autorestPath
if ($LASTEXITCODE)
{
Write-Host "##[error]Error running autorest.gotest"
exit $LASTEXITCODE
}
}
if ($format)
{
Write-Host "##[command]Executing gofmt -s -w . in " $sdkDirectory
gofmt -s -w .
if ($LASTEXITCODE) { exit $LASTEXITCODE }
}
if ($tidy)
{
Write-Host "##[command]Executing go mod tidy in " $sdkDirectory
go mod tidy
if ($LASTEXITCODE) { exit $LASTEXITCODE }
}
if (!$skipBuild)
{
Write-Host "##[command]Executing go build -x -v ./... in " $sdkDirectory
go build -x -v ./...
Write-Host "##[command]Build Complete!"
if ($LASTEXITCODE) { exit $LASTEXITCODE }
}
if ($vet)
{
Write-Host "##[command]Executing go vet ./... in " $sdkDirectory
go vet ./...
}
}
. (Join-Path $PSScriptRoot .. common scripts common.ps1)
function PrepareMockServer()
{
# install mock server
$folder = Join-Path $env:TEMP "$MOCK_SERVER_DIR"
StopMockServer
try
{
Remove-Item -Recurse -Force -Path $folder
}
catch
{
Write-Host "Mock service host folder: $folder not existed"
}
New-Item -ItemType Directory -Force -Path $folder
Set-Location $folder
npm install @azure-tools/mock-service-host
}
function StartMockServer()
{
param(
[string]$specDir = "",
[string]$rpSDKFolder,
[string]$autorestConfigFile = "autorest.md"
)
$folder = Join-Path $env:TEMP "$MOCK_SERVER_DIR"
Set-Location $folder
# change .env file to use the specific swagger file
$envFile = Join-Path $folder .env
$swaggerInfo = GetSwaggerInfo -specDir $specDir -rpSDKFolder $rpSDKFolder -autorestConfigFile $autorestConfigFile
New-Item -Path $envFile -ItemType File -Value '' -Force
$swaggerPath = $swaggerInfo.path
$specName = $swaggerInfo.specName
if ($swaggerInfo.isRepoUrl -eq $true)
{
Add-Content $envFile "specRetrievalGitUrl=$swaggerPath"
if ([string]::IsNullOrEmpty($swaggerInfo.branch) -eq $false)
{
Add-Content $envFile "specRetrievalGitBranch=$($swaggerInfo.branch)"
}
if ([string]::IsNullOrEmpty($swaggerInfo.commitID) -eq $false)
{
Add-Content $envFile "specRetrievalGitCommitID=$($swaggerInfo.commitID)"
}
Add-Content $envFile "validationPathsPattern=specification/$specName/resource-manager/**/*.json"
}
else
{
Write-Host "start Mock Test from local swagger"
Add-Content $envFile "specRetrievalMethod=filesystem
specRetrievalLocalRelativePath=$swaggerPath
validationPathsPattern=$swaggerPath/*/resource-manager/**/*.json"
}
# start mock server and check status
Start-Job -Name $MOCK_SERVER_NAME -ScriptBlock { node node_modules/@azure-tools/mock-service-host/dist/src/main.js 2>&1 }
$output = Receive-Job $MOCK_SERVER_NAME
Write-Host "Mock sever status: `n $("$output")"
$time = 0
try
{
while ("$output" -notmatch $MOCK_SERVER_READY)
{
if ($time -gt $MOCK_SERVER_WAIT_TIME)
{
Write-Host "##[error] mock server start timeout"
StopMockServer
exit 1
}
Write-Host "Server not ready, wait for annother 10 seconds"
$time += 10
Start-Sleep -Seconds 10
$output = Receive-Job $MOCK_SERVER_NAME
Write-Host "Mock sever status: `n $("$output")"
}
}
catch
{
Write-Host "##[error]wait for mock server start:`n$_"
exit 1
}
}
function StopMockServer()
{
try
{
Stop-Job -Name $MOCK_SERVER_NAME
}
catch
{
Write-Host "##[error]can not stop mock server:`n$_"
}
}
function GetSwaggerInfo()
{
param(
[string]$specDir = "",
[string]$rpSDKFolder,
[string]$autorestConfigFile = "autorest.md"
)
if ([string]::IsNullOrEmpty($rpSDKFolder))
{
if ([string]::IsNullOrEmpty($specDir))
{
$swaggerInfo = [PSCustomObject]@{
isRepoUrl = $true
path = "https://github.com/Azure/azure-rest-api-specs"
specName = "*"
org = "Azure"
branch = "main"
commitID = ""
}
}
else
{
$swaggerInfo = [PSCustomObject]@{
isRepoUrl = $false
path = $specDir
specName = "*"
org = ""
branch = ""
commitID = ""
}
}
}
else
{
$file = "$rpSDKFolder/$autorestConfigFile"
$readmefile = (Select-String -Path $file -Pattern ".*readme.md" | ForEach-Object { $_.Matches.Value }) -replace "require *:|- ", ""
if ([string]::IsNullOrEmpty($readmefile))
{
Write-Host "Cannot get swagger info"
exit 1
}
$readmefile = $readmefile -replace "\\", "/"
$isRepoUrl = $false
$path = ""
$specName = ""
$org = ""
$branch = ""
$commitID = ""
$readmefile = $readmefile.Trim()
if ($readmefile.StartsWith("http"))
{
$isRepoUrl = $true
}
if ($isRepoUrl -eq $true)
{
$swaggerInfoRegex = ".*github.*.com\/(?<org>.*)\/azure-rest-api-specs\/blob\/(?<commitID>[0-9a-f]{40})\/specification\/(?<specName>.*)\/resource-manager\/readme.md"
$rawSwaggerInfoRegex = ".*github.*.com\/(?<org>.*)\/azure-rest-api-specs\/(?<commitID>[0-9a-f]{40})\/specification\/(?<specName>.*)\/resource-manager\/readme.md"
$swaggerNoCommitRegex = ".*github.*.com\/(?<org>.*)\/azure-rest-api-specs\/(blob\/)?(?<branch>.*)\/specification\/(?<specName>.*)\/resource-manager\/readme.md"
try
{
if ($readmefile -match $swaggerInfoRegex)
{
$org = $matches["org"]
$specName = $matches["specName"]
$commitID = $matches["commitID"]
$path = "https://github.com/$org/azure-rest-api-specs"
}
elseif ($readmefile -match $rawSwaggerInfoRegex)
{
$org = $matches["org"]
$specName = $matches["specName"]
$commitID = $matches["commitID"]
$path = "https://github.com/$org/azure-rest-api-specs"
}
elseif ($readmefile -match $swaggerNoCommitRegex)
{
$org = $matches["org"]
$specName = $matches["specName"]
$branch = $matches["branch"]
$path = "https://github.com/$org/azure-rest-api-specs"
}
}
catch
{
Write-Error "Error parsing swagger info"
Write-Error $_
}
}
else
{
$paths = $readmefile.split("/");
$len = $paths.count
if ($len -gt 2)
{
$specName = $paths[$len - 3]
$path = ($paths[0..($len - 4)]) -join "/"
}
}
$swaggerInfo = [PSCustomObject]@{
isRepoUrl = $isRepoUrl
path = $path
specName = $specName
org = $org
branch = $branch
commitID = $commitID
}
}
return $swaggerInfo
}
function TestAndGenerateReport($dir)
{
Set-Location $dir
# dependencies for go coverage report generation
go install github.com/jstemmer/go-junit-report/v2@v2.1.0
go install github.com/axw/gocov/gocov@v1.2.1
go install github.com/AlekSi/gocov-xml@v1.1.0
go install github.com/matm/gocov-html/cmd/gocov-html@v1.4.0
# set azidentity env for mock test
$Env:AZURE_TENANT_ID = "mock-test"
$Env:AZURE_CLIENT_ID = "mock-test"
$Env:AZURE_USERNAME = "mock-test"
$Env:AZURE_PASSWORD = "mock-test"
# do test with corage report and convert to cobertura format
Write-Host "go cmd: go test -v -coverprofile coverage.txt | Tee-Object -FilePath outfile.txt"
go test -v -coverprofile coverage.txt -run TestMockTest | Tee-Object -FilePath outfile.txt
Write-Host "report.xml: Get-Content outfile.txt | go-junit-report > report.xml"
Get-Content outfile.txt | go-junit-report > report.xml
Write-Host "coverage.json: gocov convert ./coverage.txt > ./coverage.json"
gocov convert ./coverage.txt > ./coverage.json
Write-Host "coverage.xml: Get-Content ./coverage.json | gocov-xml > ./coverage.xml"
Get-Content ./coverage.json | gocov-xml > ./coverage.xml
Write-Host "coverage.html: Get-Content ./coverage.json | gocov-html > ./coverage.html"
Get-Content ./coverage.json | gocov-html > ./coverage.html
}
function JudgeExitCode($errorMsg = "execution error")
{
if (!$?)
{
Write-Host "##[error] $errorMsg"
exit $LASTEXITCODE
}
}
function ExecuteSingleTest($sdk, $needRunMockServer = $true)
{
Write-Host "Start mock server"
if ($needRunMockServer -eq $true)
{
StartMockServer -rpSDKFolder $sdk.DirectoryPath
}
Write-Host "Execute mock test for $($sdk.Name)"
TestAndGenerateReport $sdk.DirectoryPath
Write-Host "Stop mock server"
if ($needRunMockServer -eq $true)
{
StopMockServer
}
}