-
Notifications
You must be signed in to change notification settings - Fork 211
Expand file tree
/
Copy pathTest-PowerShell.ps1
More file actions
294 lines (243 loc) · 9.46 KB
/
Test-PowerShell.ps1
File metadata and controls
294 lines (243 loc) · 9.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
<#
.SYNOPSIS
Runs Pester tests.
.DESCRIPTION
The Test-PowerShell command runs Pester tests for the FinOps toolkit. By default, only unit tests are run. If only one test type is specified, only that test type will be run. If multiple are specified, each of them will be run. Other options will apply to all test types that are selected. Select -AllTests to run all test types.
To investigate the previous test run, use $global:ftk_TestPowerShell_Results.
To view a summary of only the failed tests, use $global:ftk_TestPowerShell_Summary.
To view the configuration used to re-run previously failed tests, use $global:ftk_TestPowerShell_FailedTests.
.PARAMETER Cost
Optional. Indicates whether to run Cost Management tests.
.PARAMETER Data
Optional. Indicates whether to run open data tests.
.PARAMETER Exports
Optional. Indicates whether to run Cost Management export tests.
.PARAMETER FOCUS
Optional. Indicates whether to run FOCUS tests.
.PARAMETER Hubs
Optional. Indicates whether to run FinOps hubs tests.
.PARAMETER Toolkit
Optional. Indicates whether to run FinOps toolkit tests.
.PARAMETER Actions
Optional. Indicates whether to run GitHub Actions tests.
.PARAMETER Private
Optional. Indicates whether to run private tests. Default = false.
.PARAMETER Integration
Optional. Indicates whether to run integration tests, which take more time than unit tests by testing external dependencies. Default = false.
.PARAMETER Lint
Optional. Indicates whether to run lint tests, which validate local files are meeting dev standards. Default = false.
.PARAMETER Unit
Optional. Indicates whether to run unit tests. Default = true.
.PARAMETER AllTests
Optional. Indicates whether to run all lint, unit, and integration tests. If set, this overrides Lint, Unit, and Integration options. Default = false.
.PARAMETER RunFailed
Optional. Indicates whether to re-run previously failed tests. This can only be run after a run fails. Only the failed tests will be re-run. If there a no previous run details, nothing will run. Default = false.
#>
[CmdletBinding()]
param (
[switch]
$Cost,
[switch]
$Data,
[switch]
$Exports,
[switch]
$FOCUS,
[switch]
$Hubs,
[switch]
$Toolkit,
[switch]
$Actions,
[switch]
$Private,
[switch]
$Integration,
[switch]
$Lint,
[switch]
$Unit,
[switch]
$AllTests,
[switch]
$RunFailed
)
# Select tests to run
if ($RunFailed)
{
if ($null -eq $global:ftk_TestPowerShell_FailedTests)
{
Write-Host 'No failed tests to re-run'
return
}
else
{
Write-Host "Re-running $($global:ftk_TestPowerShell_FailedTests.Filter.FullName.Value.Count) failed test(s)..."
$config = $global:ftk_TestPowerShell_FailedTests
}
}
else
{
$typesToRun = @(
if ($AllTests -or $Lint) { 'Lint' }
if ($AllTests -or $Integration) { 'Integration' }
if ($AllTests -or $Unit -or (-not $Lint -and -not $Integration)) { 'Unit' }
)
if ($typesToRun.Count -eq 3) { $typesToRun = '*' }
$testsToRun = @()
if ($Cost) { $testsToRun += '*-FinOpsCost*', 'Cost*' }
if ($Data) { $testsToRun += '*-OpenData*', '*-FinOpsPricingUnit*', '*-FinOpsRegion*', '*-FinOpsResourceType*', '*-FinOpsService*' }
if ($Exports) { $testsToRun += '*-FinOpsCostExport*', 'CostExports.Tests.ps1' }
if ($FOCUS) { $testsToRun += '*-FinOpsSchema*', 'FOCUS.Tests.ps1' }
if ($Hubs) { $testsToRun += '*-FinOpsHub*', '*-Hub*', 'Hubs.Tests.ps1' }
if ($Toolkit) { $testsToRun += 'Toolkit.Tests.ps1', '*-FinOpsToolkit*' }
if ($Actions) { $testsToRun += 'Action.*.Tests.ps1' }
if ($Private) { $testsToRun += (Get-ChildItem -Path "$PSScriptRoot/../powershell/Tests/$testType/Unit" -Exclude *-FinOps*, *-Hub*, *-OpenData* -Name *.Tests.ps1) }
if (-not $testsToRun) { $testsToRun = "*" }
Write-Host ''
Write-Host ("Finding <$($typesToRun -join '|')>/<$($testsToRun -join '|')> tests..." -replace '<\*>/', '' -replace '<([^\|>]+)>', '$1' -replace '\*\-?', '' -replace '/ tests', ' tests') -NoNewline
$testsToRun = $typesToRun `
| ForEach-Object {
$testType = $_
$testsToRun | ForEach-Object {
$path = "$PSScriptRoot/../powershell/Tests/$testType/$_"
if ((Get-ChildItem $path -ErrorAction SilentlyContinue).Count -gt 0)
{
return $path
}
}
}
Write-Host "$($testsToRun.Count) found"
Write-Host ''
if (-not $testsToRun)
{
return
}
$config = New-PesterConfiguration
$config.Run.Path = $testsToRun | Select-Object -Unique
}
Write-Host '--------------------------------------------------'
Write-Host ''
#$relativePath = ($_ -replace '\\', '/' -split '/')[-2..-1] -join '/' -replace '.Tests.ps1', ''
#if ((Get-ChildItem $_).Count -eq 0)
#{
# Write-Host "No tests found: $relativePath"
#}
#else
#{
# Write-Host "Running $relativePath tests..."
$config.Run.PassThru = $true
$config.Output.Verbosity = 'Detailed'
$results = $global:ftk_TestPowerShell_Results = Invoke-Pester -Configuration $config
#}
#
# DEBUG: Write output to debug -- $results.FailedBlocks.Blocks.Blocks.Tests | Select-Object -Property * -ExcludeProperty Block, Root, Parent, ScriptBlock, *Duration | ConvertTo-Json -Depth 4 | Out-File "results.json"
function sum($property)
{
$results | ForEach-Object { $_.$property } | Measure-Object -Sum | Select-Object -ExpandProperty Sum
}
$script:testSummary = @()
function summarize($info)
{
$info | ForEach-Object {
if ($_.Parent.Name -ne 'Root')
{
$parent = $_.Block ?? $_.Parent
$level = summarize $parent
}
else
{
$level = 0
}
$script:testSummary += [PSCustomObject]@{
Id = $_.ExpandedPath
Name = $_.ExpandedName
Type = $_.ItemType
File = $_.BlockContainer.Item.FullName
Level = ++$level
Error = $_.ErrorRecord.Exception | Where-Object { -not [string]::IsNullOrEmpty($_.Message) }
}
}
return $level
}
if ($null -eq $results)
{
Write-Host 'No tests found'
return
}
Write-Host ''
Write-Host '=================================================='
Write-Host ''
Write-Host $results.Result.ToUpper() -ForegroundColor (@{ Passed = 'Green'; Failed = 'Red' }.($results.Result) ?? 'Yellow')
Write-Host ''
# Summarize skipped, pending, and not run tests
if ($results.SkippedCount -gt 0 -or $results.PendingCount -gt 0 -or $results.NotRunCount -gt 0)
{
Write-Host "$(sum SkippedCount) skipped, $(sum PendingCount) pending, and $(sum NotRunCount) not run" -ForegroundColor DarkGray
}
if ($results.PassedCount -gt 0)
{
Write-Host "$(sum PassedCount) of $(sum TotalCount) tests passed" -ForegroundColor Green
}
# Summarize failed tests
if ($results.FailedCount -gt 0 -or $results.FailedContainerCount -gt 0 -or $results.Failed)
{
Write-Host "$(sum FailedCount) failed tests and $(sum FailedContainerCount) failed containers" -ForegroundColor Red
# Generate test summary
$null = summarize $results.Failed
$global:ftk_TestPowerShell_Summary = $script:testSummary = $script:testSummary `
| Select-Object -Property * -Unique `
| Sort-Object -Property Path
$script:testSummary `
| ForEach-Object {
# Determine how much spacing to give for nesting
$spaces = $(' ' * $_.Level)
if ($_.Error.Count -gt 0)
{
$x = '⚠️ '
$color = 'Red'
}
else
{
$x = ' '
$color = 'DarkGray'
}
if ($_.Level -eq 1) { Write-Host '' }
Write-Host "$spaces$x$($_.Name)" -ForegroundColor $color
$_.Error | ForEach-Object {
Write-Host "$spaces └╴" -ForegroundColor DarkGray -NoNewline
Write-Host "$($_.Message)" -ForegroundColor Yellow
if ($_.StackTrace)
{
$_.StackTrace -replace ' at', ' ├╴at' -replace '├([^├]+)$', '└$1' -split '\r\n' `
| ForEach-Object {
$segments = $_ -split '╴'
Write-Host "$spaces$($segments[0])╴" -ForegroundColor DarkGray -NoNewline
Write-Host "$($segments[1])" -ForegroundColor Yellow
}
}
}
}
# Save failed tests
$global:ftk_TestPowerShell_FailedTests = New-PesterConfiguration
$global:ftk_TestPowerShell_FailedTests.Run.Path = $script:testSummary.File | Where-Object { $_ } | Select-Object -Unique
$global:ftk_TestPowerShell_FailedTests.Filter.FullName = $script:testSummary | Where-Object { $_.Type -eq 'Test' } | ForEach-Object { "*$($_.Id -replace '([\\:\[\]])', '?')" }
if ($null -ne $global:ftk_TestPowerShell_FailedTests)
{
Write-Host ''
Write-Host "To re-run the $($global:ftk_TestPowerShell_FailedTests.Filter.FullName.Value.Count) failed test(s), use: " -NoNewline -ForegroundColor White
Write-Host "& '$("$PSScriptRoot/Test-PowerShell.ps1" | Resolve-Path -Relative)' -RunFailed" -ForegroundColor Cyan
}
}
else
{
# Reset failed tests array
$global:ftk_TestPowerShell_FailedTests = $null
}
Write-Host ''
Write-Host 'For details, see $global:ftk_TestPowerShell_Results' -ForegroundColor DarkGray
Write-Host ''
Write-Host '--------------------------------------------------'
Write-Host ''