Skip to content

Commit 1440505

Browse files
Afroz Mohammedafroz429
authored andcommitted
added batch module loading for aws.tools modules, added import module testing for windows powershell
1 parent 74fd959 commit 1440505

File tree

1 file changed

+196
-20
lines changed

1 file changed

+196
-20
lines changed

buildtools/Confirm-StagedArtifact.ps1

Lines changed: 196 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,35 +13,63 @@
1313
(i.e. .\AWSPowerShell .\AWSPowerShell.NetCore and .\AWS.Tools).
1414
1515
.Example
16-
Confirm-StagedArtifact -ExpectedVersion 3.3.283.0
16+
# On Windows Prod
17+
Confirm-StagedArtifact.ps1 -VerifySigning 'true' -AdditionalModuleChecks 'false'
18+
.Example
19+
# On Windows Dev
20+
Confirm-StagedArtifact.ps1 -VerifySigning 'false' -AdditionalModuleChecks 'false'
21+
.Example
22+
# On Linux
23+
Confirm-StagedArtifact.ps1 -VerifySigning 'false' -AdditionalModuleChecks 'true' -ExpectedVersion 4.1.724.1
1724
#>
1825
Param (
1926
# The expected version of the module. This will be verified against
2027
# the module manifest and the running binary.
21-
[Parameter(Mandatory = $true, Position = 0)]
28+
[Parameter()]
2229
[string]$ExpectedVersion,
2330

2431
# Determines if signing will be verified. This must be true for production
2532
# release environments.
2633
[Parameter()]
2734
[string] $VerifySigning = "true",
2835

36+
# By default all modules AWSPowerShell, AWSPowerShell.NetCore and AWS.Tools modules are imported in pwsh on linux and (pwsh and windows powershell) on windows.
37+
# Get-S3Bucket ran for AWSPowerShell, AWSPowerShell.NetCore and AWS.Tools.S3.
38+
# $AdditionalModuleChecks test the following.
39+
# test module manifest,
40+
# test module manifest version,
41+
# test changelog
42+
[Parameter()]
43+
[string] $AdditionalModuleChecks = "true",
44+
2945
# Specifies the type of build that is being verified. For PREVIEW build types AWSPowerShell.NetCore
3046
# will be verified. Otherwise AWSPowerShell, AWSPowerShell.NetCore, and AWS.Tools.* will be verified.
3147
[Parameter()]
3248
[string] $BuildType = "RELEASE"
3349
)
3450

35-
function ValidateModule([string]$modulePath, [bool]$verifyChangeLog, [bool]$testVersion, [bool]$signingCheck, [string]$cmdletToTest) {
51+
function ValidateModule{
52+
param(
53+
[Parameter(Mandatory = $true)]
54+
[string]$modulePath,
55+
[Parameter(Mandatory = $true)]
56+
[bool]$verifyChangeLog,
57+
[Parameter(Mandatory = $true)]
58+
[bool]$testVersion,
59+
[Parameter(Mandatory = $true)]
60+
[bool]$signingCheck,
61+
[Parameter(Mandatory = $true)]
62+
[string]$cmdletToTest,
63+
[Parameter(Mandatory = $true)]
64+
[bool]$testCmdlets)
3665

3766
Write-Host "Validating module $modulePath"
3867

3968
$manifestPath = (Get-ChildItem -Path "$modulePath\*.psd1").FullName
40-
Write-Host "Verifying version in manifest $manifestPath"
41-
42-
$manifest = Test-ModuleManifest $manifestPath -ErrorAction 'Stop'
4369

4470
if ($testVersion) {
71+
Write-Host "Verifying version in manifest $manifestPath"
72+
$manifest = Test-ModuleManifest $manifestPath -ErrorAction 'Stop'
4573
$manifestVersion = $manifest.Version.ToString()
4674
Write-Host "Found version $manifestVersion"
4775

@@ -96,29 +124,165 @@ function ValidateModule([string]$modulePath, [bool]$verifyChangeLog, [bool]$test
96124
}
97125
}
98126

99-
Write-Host 'Testing module'
100-
if (-not ($PSVersionTable.PSVersion.Major -gt 6 -or ($PSVersionTable.PSVersion.Major -eq 6 -And $PSVersionTable.PSVersion.Minor -ge 1))) {
101-
throw "PowerShell version 6.1 or later is required, found version $($PSVersionTable.PSVersion)"
127+
if ($testCmdlets) {
128+
if (-not($IsLinux -and $modulePath -eq 'AWSPowerShell')) {
129+
# Skip AWSPowerShell import in pwsh on Linux
130+
Write-Host 'Testing module in pwsh'
131+
if (-not ($PSVersionTable.PSVersion.Major -gt 6 -or ($PSVersionTable.PSVersion.Major -eq 6 -And $PSVersionTable.PSVersion.Minor -ge 1))) {
132+
throw "PowerShell version 6.1 or later is required, found version $($PSVersionTable.PSVersion)"
133+
}
134+
$testOutput = pwsh -noprofile -Command "`$ErrorActionPreference = 'Stop' ; Import-Module '$manifestPath' ; $cmdletToTest"
135+
if ($LastExitCode -eq 0) {
136+
Write-Host '...module loading pwsh - PASS'
137+
}
138+
else {
139+
throw "The module failed to load PowerShell `n" + $testOutput
140+
}
141+
}
142+
if ($IsWindows -and $modulePath -ne 'AWSPowerShell.NetCore') {
143+
# Skip AWSPowerShell.NetCore import in Windows PowerShell
144+
Write-Host 'Testing module in powershell.exe'
145+
$testOutput = powershell -noprofile -Command "`$ErrorActionPreference = 'Stop' ; Import-Module '$manifestPath' ; $cmdletToTest"
146+
if ($LastExitCode -eq 0) {
147+
Write-Host '...module loading in Windows PowerShell - PASS'
148+
}
149+
else {
150+
throw "The module failed to load in Windows PowerShell `n" + $testOutput
151+
}
152+
}
153+
}
154+
}
155+
function StartBatchImportJobs {
156+
param (
157+
[Parameter(Mandatory = $true)]
158+
[array]$manifestBatches,
159+
[Parameter(Mandatory = $true)]
160+
[string]$cmdletTest,
161+
[Parameter(Mandatory = $true)]
162+
[string]$shellType,
163+
[int]$maxConcurrentJobs = 5
164+
)
165+
166+
Write-Host "Testing AWS tools modules import in $shellType"
167+
$jobs = @()
168+
169+
foreach ($batch in $manifestBatches) {
170+
$jobs += ImportModulesBatch -manifestBatch $batch -cmdletTest $cmdletTest -shellType $shellType
171+
172+
# Wait if maximum concurrent jobs is reached
173+
while ((Get-Job -State Running).Count -ge $maxConcurrentJobs) {
174+
Start-Sleep -Seconds 1
175+
}
176+
}
177+
178+
return $jobs
179+
}
180+
181+
function TestImportModule {
182+
param (
183+
[Parameter(Mandatory = $true)]
184+
[string[]]$manifestPaths,
185+
[Parameter(Mandatory = $true)]
186+
[string]$cmdletTest,
187+
[int]$batchSize = 25,
188+
[int]$maxConcurrentJobs = 5
189+
)
190+
191+
# Split into batches
192+
$manifestBatches = SplitIntoBatches -manifestPaths $manifestPaths -batchSize $batchSize
193+
194+
# Test in pwsh
195+
$pwshJobs = StartBatchImportJobs -manifestBatches $manifestBatches -cmdletTest $cmdletTest -shellType 'pwsh' -maxConcurrentJobs $maxConcurrentJobs
196+
ProcessImportJobs -jobs $pwshJobs -shellName 'PowerShell'
197+
198+
# Test in Windows PowerShell if on Windows
199+
if ($IsWindows) {
200+
$winPsJobs = StartBatchImportJobs -manifestBatches $manifestBatches -cmdletTest $cmdletTest -shellType 'powershell' -maxConcurrentJobs $maxConcurrentJobs
201+
ProcessImportJobs -jobs $winPsJobs -shellName 'Windows PowerShell'
102202
}
103-
$testOutput = pwsh -noprofile -Command "`$ErrorActionPreference = 'Stop' ; Import-Module '$manifestPath' ; $cmdletToTest"
104-
if ($LastExitCode -eq 0) {
105-
Write-Host '...module loading - PASS'
203+
}
204+
function ImportModulesBatch {
205+
param (
206+
[string[]]$manifestBatch,
207+
[string]$cmdletTest,
208+
[string]$shellType # 'pwsh' or 'powershell'
209+
)
210+
211+
$job = Start-Job -ScriptBlock {
212+
param($manifests, $cmdletTest, $shell)
213+
214+
& $shell -noprofile -Command {
215+
param($manifests, $cmdletTest)
216+
$ErrorActionPreference = 'Stop'
217+
218+
foreach ($manifest in $manifests) {
219+
Import-Module -Name $manifest
220+
}
221+
222+
# Execute the test cmdlet after all modules are imported
223+
Invoke-Expression $cmdletTest
224+
} -Args $manifests, $cmdletTest
225+
226+
} -ArgumentList $manifestBatch, $cmdletTest, $shellType
227+
228+
return $job
229+
}
230+
231+
function ProcessImportJobs {
232+
param (
233+
[System.Management.Automation.Job[]]$jobs,
234+
[string]$shellName
235+
)
236+
237+
$jobs | Wait-Job | ForEach-Object {
238+
$result = Receive-Job -Job $_
239+
if ($_.State -eq 'Failed' -or $_.ChildJobs[0].Error) {
240+
Remove-Job -Job $_
241+
throw "The modules failed to load in $shellName `n" + $result
242+
}
243+
Write-Host "...batch module loading in $shellName - PASS"
244+
Remove-Job -Job $_
106245
}
107-
else {
108-
throw "The module failed to load `n" + $testOutput
246+
}
247+
248+
function SplitIntoBatches {
249+
param (
250+
[string[]]$manifestPaths,
251+
[int]$batchSize
252+
)
253+
254+
$manifestBatches = @()
255+
for ($i = 0; $i -lt $manifestPaths.Count; $i += $batchSize) {
256+
$batch = $manifestPaths[$i..([Math]::Min($i + $batchSize - 1, $manifestPaths.Count - 1))]
257+
$manifestBatches += , $batch
109258
}
259+
return $manifestBatches
110260
}
111261

262+
112263
if (Get-Module AWSPowerShell, AWSPowerShell.NetCore, AWS.Tools.*) {
113264
throw 'Cannot validate modules if any AWS Tools for PowerShell module is already imported'
114265
}
115266

267+
if ($AdditionalModuleChecks -eq 'true' -and [string]::IsNullOrEmpty($ExpectedVersion)) {
268+
throw '$ExpectedVersion is required when $AdditionalModuleChecks is true'
269+
}
116270
$signingCheck = $true
117271
if ($VerifySigning -eq 'false') {
118272
$signingCheck = $false
119273
}
120274

275+
276+
$testCmdlets = $true
277+
121278
$testVersion = $true
279+
$verifyChangeLog = $true
280+
281+
if ($AdditionalModuleChecks -eq 'false') {
282+
$testVersion = $false
283+
$verifyChangeLog = $false
284+
}
285+
122286
$validateModules = @('AWSPowerShell', 'AWSPowerShell.NetCore')
123287
if ($BuildType -eq 'PREVIEW') {
124288
$validateModules = @('AWSPowerShell.NetCore')
@@ -127,7 +291,7 @@ if ($BuildType -eq 'PREVIEW') {
127291

128292
$validateModules | ForEach-Object {
129293
try {
130-
ValidateModule $_ $true $testVersion $signingCheck { Get-S3Bucket -ProfileName test-runner }
294+
ValidateModule $_ $verifyChangeLog $testVersion $signingCheck { Get-S3Bucket -ProfileName test-runner } $testCmdlets
131295
Write-Host "PASSED validation for module $_"
132296
}
133297
catch {
@@ -141,25 +305,37 @@ if ($BuildType -ne 'PREVIEW') {
141305
Import-Module PowerShellGet
142306

143307
$OldPath = $Env:PSModulePath
144-
$Env:PSModulePath = $Env:PSModulePath + ';' + $awsToolsDeploymentPath
308+
$envPathSeperator = ':'
309+
if ($IsWindows) {
310+
$envPathSeperator = ';'
311+
}
312+
$Env:PSModulePath = $Env:PSModulePath + $envPathSeperator + $awsToolsDeploymentPath
145313

146-
Get-ChildItem $awsToolsDeploymentPath -Directory | ForEach-Object {
314+
$awstoolsModules = Get-ChildItem $awsToolsDeploymentPath -Directory
315+
$awstoolsModules | ForEach-Object {
316+
# Only test module import module and cmdlet for S3.
317+
# All other AWS Tools modules will be tested with TestImportModule to speed up testing
147318
try {
148319
if ($_.Name -eq 'AWS.Tools.S3') {
149-
ValidateModule $_ $false $true $signingCheck { Get-S3Bucket -ProfileName test-runner }
320+
ValidateModule $_ $false $testVersion $signingCheck { Get-S3Bucket -ProfileName test-runner } $testCmdlets
150321
}
151322
elseif ($_.Name -eq 'AWS.Tools.Installer') {
152-
ValidateModule $_ $false $false $signingCheck { }
323+
ValidateModule $_ $false $false $signingCheck { } $false
153324
}
154325
else {
155-
ValidateModule $_ $false $true $signingCheck { Get-AWSPowerShellVersion }
326+
ValidateModule $_ $false $testVersion $signingCheck { } $false
156327
}
157328
Write-Host "PASSED validation for module $_"
158329
}
159330
catch {
160331
throw "FAILED validation for module $_, error $error"
161332
}
162333
}
334+
# Test Module Import for AWS Tools Modules
335+
$moduleManifestPaths = $awstoolsModules.where{ $_.Name -ne 'AWS.Tools.Installer' }.foreach{ $_.FullName + '/' + $_.Name + '.psd1' }
336+
337+
TestImportModule -manifestPaths $moduleManifestPaths -cmdletTest 'Get-AWSPowerShellVersion'
338+
163339

164340
$Env:PSModulePath = $OldPath
165341
}

0 commit comments

Comments
 (0)