312 строки
10 KiB
PowerShell
312 строки
10 KiB
PowerShell
#!/usr/bin/env pwsh
|
|
|
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
# Licensed under the MIT License.
|
|
|
|
#Requires -Version 6.0
|
|
#Requires -PSEdition Core
|
|
|
|
[CmdletBinding(DefaultParameterSetName="Provisioner")]
|
|
|
|
param (
|
|
[Parameter(ParameterSetName = 'Provisioner', Mandatory = $true)]
|
|
[ValidatePattern('^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$')]
|
|
[string] $TestApplicationId,
|
|
|
|
[Parameter()]
|
|
[string] $TestApplicationSecret,
|
|
|
|
[Parameter()]
|
|
[string] $TestApplicationOid,
|
|
|
|
[Parameter(ParameterSetName = 'Provisioner', Mandatory = $true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string] $TenantId,
|
|
|
|
[Parameter(ParameterSetName = 'Provisioner')]
|
|
[ValidatePattern('^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$')]
|
|
[string] $SubscriptionId,
|
|
|
|
[Parameter()]
|
|
[string] $Location = '',
|
|
|
|
[Parameter()]
|
|
[string] $Environment = 'AzureCloud',
|
|
|
|
[Parameter()]
|
|
[hashtable] $AdditionalParameters,
|
|
|
|
[Parameter()]
|
|
[string] $ServiceDirectory = '*',
|
|
|
|
[Parameter()]
|
|
[switch] $CI = ($null -ne $env:SYSTEM_TEAMPROJECTID),
|
|
|
|
[Parameter()]
|
|
[switch] $Daily,
|
|
|
|
[Parameter()]
|
|
[string] $TagOverride,
|
|
|
|
[Parameter()]
|
|
[array] $TagOverridePackages,
|
|
|
|
# DryRun will generate the smoke test run manifest, but will skip deploying any resources.
|
|
# This can be useful for testing what projects will be configured to run for a given command.
|
|
[Parameter(ParameterSetName = 'DryRun')]
|
|
[switch] $DryRun,
|
|
|
|
# Captures any arguments not declared here (prevents no parameter errors)
|
|
[Parameter(ValueFromRemainingArguments = $true)]
|
|
$RemainingArguments
|
|
)
|
|
|
|
$repoRoot = Resolve-Path -Path "$PSScriptRoot../../../"
|
|
. "$repoRoot/eng/common/scripts/logging.ps1"
|
|
|
|
function Set-EnvironmentVariable {
|
|
param([string] $Name, [string] $Value)
|
|
|
|
if ($CI) {
|
|
Write-Host "##vso[task.setvariable variable=_$Name;issecret=true;]$($Value)"
|
|
Write-Host "##vso[task.setvariable variable=$Name;]$($Value)"
|
|
}
|
|
else {
|
|
Write-Verbose "Setting local environment variable: $Name = ***"
|
|
Set-Item -Path "env:$Name" -Value $Value
|
|
}
|
|
}
|
|
|
|
function Set-EnvironmentVariables {
|
|
Write-Verbose "Setting AAD environment variables for Test Application..."
|
|
Set-EnvironmentVariable -Name AZURE_CLIENT_ID -Value $TestApplicationId
|
|
Set-EnvironmentVariable -Name AZURE_CLIENT_SECRET -Value $TestApplicationSecret
|
|
Set-EnvironmentVariable -Name AZURE_TENANT_ID -Value $TenantId
|
|
|
|
Write-Verbose "Setting cloud-specific environment variables"
|
|
$cloudEnvironment = Get-AzEnvironment -Name $Environment
|
|
Set-EnvironmentVariable -Name AZURE_AUTHORITY_HOST -Value $cloudEnvironment.ActiveDirectoryAuthority
|
|
}
|
|
|
|
function New-DeployManifest {
|
|
Write-Verbose "Detecting samples..."
|
|
$packageDir = Get-ChildItem -Directory -Path "$repoRoot/sdk/$ServiceDirectory/*" | Where-Object { Test-Path "$_/samples/*/javascript/package.json" }
|
|
|
|
$javascriptSamples = @()
|
|
$packageDir.ForEach{
|
|
$versions = (Get-Item "$_/samples/*").Name
|
|
$newestVer = $versions | Sort-Object {[int]($_ -replace '[^0-9]' -replace '(\d+).*', '$1')} -Descending | Select-Object -First 1
|
|
if($versions -contains $newestVer+"-beta") {
|
|
$newestVer += "-beta"
|
|
}
|
|
$javascriptSamples += Get-ChildItem -Path "$_/samples/$newestVer/javascript/" -Recurse -Include package.json
|
|
}
|
|
|
|
$manifest = $javascriptSamples | ForEach-Object {
|
|
# Example: azure-sdk-for-js/sdk/appconfiguration/app-configuration/samples/v1/javascript
|
|
$PackagePath = (Join-Path $_ ../../../../) | Get-Item
|
|
@{
|
|
# Package name for example "app-configuration"
|
|
Name = $PackagePath.Name;
|
|
|
|
# Path to "app-configuration" part from example
|
|
PackageDirectory = $PackagePath.FullName;
|
|
|
|
# Service Directory for example "appconfiguration"
|
|
ResourcesDirectory = $PackagePath.Parent.Name;
|
|
|
|
# Path to "javascript"
|
|
SamplesDirectory = $_.Directoryname;
|
|
}
|
|
}
|
|
|
|
return $manifest
|
|
}
|
|
|
|
function Update-SamplesForService {
|
|
Param([Parameter(Mandatory = $true)] $entry)
|
|
|
|
$sampleFiles = Get-ChildItem "$($entry.SamplesDirectory)/*.js"
|
|
foreach ($sampleFile in $sampleFiles) {
|
|
$fileContent = Get-Content -Raw $sampleFile
|
|
$fileContent = $fileContent -replace "(?s)main\(\)\.catch.*", "module.exports = { main };`n"
|
|
Set-Content -Path $sampleFile -Value $fileContent
|
|
}
|
|
}
|
|
|
|
function Update-SampleDependencies {
|
|
Param(
|
|
[Parameter(Mandatory = $true)] $sample,
|
|
[Parameter(Mandatory = $true)] $dependencies
|
|
)
|
|
|
|
# Set sample's dependencies in all-up dependencies for smoke tests
|
|
Write-Verbose "Updating local package.json with dependencies from smoke test for $($sample.Name)"
|
|
$packageSpec = (Get-Content -Path "$($sample.SamplesDirectory)/package.json"
|
|
| ConvertFrom-Json -AsHashtable)
|
|
|
|
# some @azure/ packages are not managed in our repo thus should not be overriden
|
|
$packagesToSkip = @("@azure/msal-node")
|
|
foreach ($dep in $packageSpec.dependencies.Keys) {
|
|
if ($dep.StartsWith('@azure/') -and ($dep -notin $packagesToSkip)) {
|
|
if ($Daily) {
|
|
$dependencies[$dep] = "dev"
|
|
} elseif ($dep -in $TagOverridePackages) {
|
|
# For non-daily smoke tests (i.e. release smoke tests), specifically
|
|
# override the package.json tag for the newly released package under test.
|
|
# Tag will be either 'latest' or 'next'
|
|
$dependencies[$dep] = $TagOverride
|
|
} else {
|
|
# For non-daily smoke tests and/or non-azure dependencies,
|
|
# use whatever is in the source package.json
|
|
$dependencies[$dep] = $packageSpec.dependencies[$dep]
|
|
}
|
|
}
|
|
else {
|
|
$dependencies[$dep] = $packageSpec.dependencies[$dep]
|
|
}
|
|
}
|
|
}
|
|
|
|
function Start-NewTestResourcesJob {
|
|
Param(
|
|
[Parameter(Mandatory = $true)] [System.Collections.Hashtable]$entry,
|
|
[Parameter(Mandatory = $true)] [string]$baseName,
|
|
[Parameter(Mandatory = $true)] [string]$resourceGroupName
|
|
)
|
|
|
|
Start-Job -Name $entry.Name -ScriptBlock {
|
|
&"$using:repoRoot/eng/common/TestResources/New-TestResources.ps1" `
|
|
-BaseName $using:baseName `
|
|
-ResourceGroupName $using:resourceGroupName `
|
|
-ServiceDirectory $using:entry.ResourcesDirectory `
|
|
-TestApplicationId $using:TestApplicationId `
|
|
-TestApplicationSecret $using:TestApplicationSecret `
|
|
-ProvisionerApplicationId $using:TestApplicationId `
|
|
-ProvisionerApplicationSecret $using:TestApplicationSecret `
|
|
-TestApplicationOid $using:TestApplicationOid `
|
|
-TenantId $using:TenantId `
|
|
-SubscriptionId $using:SubscriptionId `
|
|
-Location $using:Location `
|
|
-Environment $using:Environment `
|
|
-AdditionalParameters $using:AdditionalParameters `
|
|
-DeleteAfterHours 24 `
|
|
-Force `
|
|
-Verbose `
|
|
-CI:$using:CI
|
|
}
|
|
}
|
|
|
|
function Deploy-TestResources {
|
|
Param([Parameter(Mandatory = $true)] $deployManifest)
|
|
|
|
$deployedServiceDirectories = @{ }
|
|
$baseName = 't' + (New-Guid).ToString('n').Substring(0, 16)
|
|
$resourceGroupName = "rg-smoke-$baseName"
|
|
$dependencies = New-Object 'System.Collections.Generic.Dictionary[string,string]'
|
|
$runManifest = @()
|
|
|
|
# Use the same resource group name that New-TestResources.ps1 generates
|
|
Set-EnvironmentVariable -Name 'AZURE_RESOURCEGROUP_NAME' -Value $resourceGroupName
|
|
|
|
$entryDeployJobs = @()
|
|
|
|
try {
|
|
foreach ($entry in $deployManifest) {
|
|
if (!(Get-ChildItem -Path "$repoRoot/sdk/$($entry.ResourcesDirectory)" -Filter test-resources.json -Recurse)) {
|
|
Write-Verbose "Skipping $($entry.ResourcesDirectory): could not find test-resources.json"
|
|
continue
|
|
}
|
|
|
|
if ($deployedServiceDirectories.ContainsKey($entry.ResourcesDirectory) -ne $true) {
|
|
if (-not $DryRun) {
|
|
Write-Verbose "Starting deploy job for $($entry.ResourcesDirectory)"
|
|
$job = Start-NewTestResourcesJob $entry $baseName $resourceGroupName
|
|
$entryDeployJobs += $job
|
|
}
|
|
$deployedServiceDirectories[$entry.ResourcesDirectory] = $true;
|
|
}
|
|
else {
|
|
Write-Verbose "Skipping resource directory deployment (already deployed) for $($entry.ResourcesDirectory)"
|
|
}
|
|
|
|
Update-SamplesForService $entry
|
|
Update-SampleDependencies $entry $dependencies
|
|
$runManifest += $entry
|
|
}
|
|
|
|
if (-not $DryRun) {
|
|
Write-Verbose "Waiting for all deploy jobs to finish (will timeout after 30 minutes)..."
|
|
$entryDeployJobs | Wait-Job -TimeoutSec (30*60)
|
|
if ($entryDeployJobs | Where-Object {$_.State -eq "Running"}) {
|
|
$entryDeployJobs
|
|
throw "Timed out waiting for deploy jobs to finish:"
|
|
}
|
|
|
|
foreach ($job in $entryDeployJobs) {
|
|
if ($job.State -eq [System.Management.Automation.JobState]::Failed) {
|
|
$errorMsg = $job.ChildJobs[0].JobStateInfo.Reason.Message
|
|
LogWarning "Failed to deploy $($job.Name): $($errorMsg)"
|
|
Write-Host $errorMsg
|
|
continue
|
|
}
|
|
|
|
Write-Verbose "setting env"
|
|
$deployOutput = Receive-Job -Id $job.Id
|
|
foreach ($key in $deployOutput.Keys) {
|
|
Set-EnvironmentVariable -Name $key -Value $deployOutput[$key]
|
|
}
|
|
}
|
|
}
|
|
} finally {
|
|
$entryDeployJobs | Remove-Job -Force
|
|
}
|
|
|
|
@{ Dependencies = $dependencies; RunManifest = $runManifest }
|
|
}
|
|
|
|
function Export-Configs {
|
|
Param(
|
|
[Parameter(Mandatory = $true)] [System.Collections.Generic.Dictionary[string,string]]$dependencies,
|
|
[Parameter(Mandatory = $true)] $runManifest
|
|
)
|
|
|
|
Write-Verbose "Writing run-manifest.json"
|
|
($runManifest | ConvertTo-Json -AsArray | Set-Content -Path "$repoRoot/common/smoke-test/run-manifest.json" -Force)
|
|
|
|
Write-Verbose "Writing dependencies into Smoke Test package.json"
|
|
$runnerPackageSpec = Get-Content "$repoRoot/common/smoke-test/package.json" | ConvertFrom-Json -AsHashtable
|
|
$runnerPackageSpec.dependencies = $dependencies
|
|
($runnerPackageSpec | ConvertTo-Json | Set-Content "$repoRoot/common/smoke-test/package.json")
|
|
}
|
|
|
|
function Initialize-SmokeTests {
|
|
Set-EnvironmentVariables
|
|
$deployManifest = New-DeployManifest
|
|
if (!$deployManifest) {
|
|
Write-Warning "No javascript samples found for $ServiceDirectory"
|
|
return
|
|
}
|
|
$configs = Deploy-TestResources $deployManifest
|
|
Export-Configs $configs.Dependencies $configs.RunManifest
|
|
|
|
Set-EnvironmentVariable -Name "NODE_PATH" -Value "$PSScriptRoot/node_modules"
|
|
|
|
if ($CI) {
|
|
# If in CI mark the task as successful even if there are warnings so the
|
|
# pipeline execution status shows up as red or green
|
|
Write-Host "##vso[task.complete result=Succeeded; ]DONE"
|
|
}
|
|
}
|
|
|
|
Initialize-SmokeTests
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Deploys resources, discovers and generates samples, configures local dependencies, and creates run manifest for Smoke Tests
|
|
|
|
.DESCRIPTION
|
|
|
|
|
|
#>
|