microsoft/hve-core

Public

mirrored from https://github.com/microsoft/hve-coreAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
ci/2086-enforce-powershell-coverage

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

scripts/tests/linting/DotSourceGuard.Tests.ps1

108lines · modecode

1#Requires -Modules Pester
2# Copyright (c) Microsoft Corporation.
3# SPDX-License-Identifier: MIT
4
5<#
6.SYNOPSIS
7 Regression test enforcing the dot-source guard convention.
8
9.DESCRIPTION
10 Every production script that a Pester test dot-sources must wrap its main
11 logic in the guard `if ($MyInvocation.InvocationName -ne '.')`. Without it,
12 dot-sourcing the script in a `BeforeAll` block executes the script's main
13 logic (and any top-level `exit`) during test setup, which hangs or corrupts
14 the run. This test discovers every dot-sourced target across the test suite
15 and asserts the guard is present.
16#>
17
18BeforeDiscovery {
19 $testsRoot = Join-Path $PSScriptRoot '..'
20
21 function Get-StringLiteralPath {
22 param([System.Management.Automation.Language.Ast]$Node)
23
24 $literals = $Node.FindAll({
25 param($n)
26 $n -is [System.Management.Automation.Language.StringConstantExpressionAst] -or
27 $n -is [System.Management.Automation.Language.ExpandableStringExpressionAst]
28 }, $true)
29
30 ($literals | Where-Object { $_.Value -match '\.ps1' } | Select-Object -First 1).Value
31 }
32
33 $discovered = [System.Collections.Generic.List[object]]::new()
34 $seen = [System.Collections.Generic.HashSet[string]]::new()
35
36 $testFiles = Get-ChildItem -Path $testsRoot -Recurse -Filter '*.Tests.ps1'
37
38 foreach ($testFile in $testFiles) {
39 $tokens = $null
40 $errors = $null
41 $ast = [System.Management.Automation.Language.Parser]::ParseFile(
42 $testFile.FullName, [ref]$tokens, [ref]$errors)
43
44 $dotSources = $ast.FindAll({
45 param($n)
46 $n -is [System.Management.Automation.Language.CommandAst] -and
47 $n.InvocationOperator -eq 'Dot'
48 }, $true)
49
50 foreach ($dotSource in $dotSources) {
51 $literal = Get-StringLiteralPath -Node $dotSource
52
53 if (-not $literal) {
54 # Variable indirection: resolve `$path = Join-Path ...; . $path`.
55 $variable = $dotSource.CommandElements[0] -as [System.Management.Automation.Language.VariableExpressionAst]
56 if ($variable) {
57 $name = $variable.VariablePath.UserPath -replace '^script:', ''
58 $assignment = $ast.FindAll({
59 param($n)
60 $n -is [System.Management.Automation.Language.AssignmentStatementAst]
61 }, $true) | Where-Object {
62 $_.Left.Extent.Text -match ('\$(script:)?' + [regex]::Escape($name) + '\b')
63 } | Select-Object -First 1
64
65 if ($assignment) {
66 $literal = Get-StringLiteralPath -Node $assignment.Right
67 }
68 }
69 }
70
71 if (-not $literal) { continue }
72
73 $relative = $literal -replace '\$PSScriptRoot', '' -replace '^[\\/]+', ''
74 $candidate = Join-Path $testFile.DirectoryName $relative
75 $resolved = $null
76 try {
77 $resolved = (Resolve-Path -LiteralPath $candidate -ErrorAction Stop).Path
78 }
79 catch {
80 continue
81 }
82
83 if ($resolved -and $resolved -notmatch '\.Tests\.ps1$' -and $seen.Add($resolved)) {
84 $discovered.Add(@{
85 TargetPath = $resolved
86 TargetName = Split-Path $resolved -Leaf
87 TestName = $testFile.Name
88 })
89 }
90 }
91 }
92
93 $script:DotSourcedScripts = $discovered
94}
95
96Describe 'Dot-source guard convention' -Tag 'Unit' {
97 It 'discovers at least one dot-sourced script' {
98 $DotSourcedScripts.Count | Should -BeGreaterThan 0
99 }
100
101 It '<TargetName> guards main logic from dot-sourcing (referenced by <TestName>)' -ForEach $DotSourcedScripts {
102 $content = Get-Content -LiteralPath $TargetPath -Raw
103 $content | Should -Match "InvocationName\s+-ne\s+'\." -Because (
104 "$TargetName is dot-sourced by $TestName and must wrap its main logic in " +
105 "if (`$MyInvocation.InvocationName -ne '.') so test setup does not execute it"
106 )
107 }
108}