Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 75 additions & 1 deletion azuredevops-pihole-pester-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,88 @@ steps:
- pwsh: |
Import-Module Pester -MinimumVersion 5.0.0 -Force

# On a PR build, scope the run to tests for the files that actually changed - tests/ mirrors
# PiHoleShell/Public/<Category>/ 1:1, so a changed function maps directly to its test file(s).
# Any ambiguity (shared/private code, module manifest, shared test helpers, or the diff itself
# failing) falls back to the full suite rather than risk silently skipping real coverage.
# Direct pushes to develop/main (not PR builds) always run the full suite.
$runFullSuite = $true
$testPaths = [System.Collections.Generic.List[string]]::new()

if ($env:BUILD_REASON -eq 'PullRequest') {
try {
# The default checkout is shallow, which leaves no common ancestor with the target
# branch to diff against ("no merge base") - unshallow first so the diff can work.
if ((git rev-parse --is-shallow-repository) -eq 'true') {
git fetch --unshallow --quiet
if ($LASTEXITCODE -ne 0) { throw "git fetch --unshallow failed" }
}

# Fetch with an explicit refspec so origin/<branch> is created even if the
# checkout's default fetch refspec is restricted to a single branch.
$targetBranch = $env:SYSTEM_PULLREQUEST_TARGETBRANCH -replace '^refs/heads/', ''
git fetch origin "${targetBranch}:refs/remotes/origin/${targetBranch}" --quiet
if ($LASTEXITCODE -ne 0) { throw "git fetch failed for '$targetBranch'" }

$changedFiles = git diff --name-only "origin/$targetBranch...HEAD"
if ($LASTEXITCODE -ne 0) { throw "git diff failed against 'origin/$targetBranch'" }

if ($changedFiles) {
$runFullSuite = $false

foreach ($file in $changedFiles) {
if ($runFullSuite) { break }

if ($file -match '^PiHoleShell/Private/' -or
$file -eq 'PiHoleShell/PiHoleShell.psm1' -or
$file -eq 'PiHoleShell/PiHoleShell.psd1' -or
$file -eq 'PiHoleShell/Public/Authentication/Request-PiHoleAuth.ps1' -or
$file -eq 'tests/Initialize-PiHoleTestData.ps1' -or
$file -eq 'tests/IntegrationConfig.example.ps1') {
Write-Host "Shared/core file changed ($file) - running the full suite"
$runFullSuite = $true
}
elseif ($file -match '^PiHoleShell/Public/([^/]+)/([^/]+)\.ps1$') {
$category = $Matches[1]
$function = $Matches[2]
$testDir = "tests/$category"
if (Test-Path $testDir) {
Get-ChildItem -Path $testDir -Filter "$function.*Tests.ps1" | ForEach-Object {
$testPaths.Add($_.FullName)
}
}
}
elseif ($file -match '^tests/.*\.Tests\.ps1$' -and (Test-Path $file)) {
$testPaths.Add((Resolve-Path $file).Path)
}
# Anything else (README, workflows, tools/, etc.) has no test impact - ignored.
}
}
}
catch {
Write-Warning "Could not compute changed-file test scope, falling back to the full suite: $($_.Exception.Message)"
$runFullSuite = $true
}
}

$config = New-PesterConfiguration
$config.Run.Path = './tests'
$config.Run.Exit = $true
$config.Output.Verbosity = 'Detailed'
$config.TestResult.Enabled = $true
$config.TestResult.OutputFormat = 'NUnitXml'
$config.TestResult.OutputPath = '$(testResultsFile)'

$testPaths = $testPaths | Select-Object -Unique
if ($runFullSuite -or $testPaths.Count -eq 0) {
Write-Host "Running the full test suite"
$config.Run.Path = './tests'
}
else {
Write-Host "Running scoped tests for changed files:"
$testPaths | ForEach-Object { Write-Host " $_" }
$config.Run.Path = $testPaths
}

Invoke-Pester -Configuration $config
displayName: 'Run Pester tests'
workingDirectory: '$(System.DefaultWorkingDirectory)'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

# Config availability must be known at discovery time so the -Skip parameter on each It block
# (evaluated during discovery, before BeforeAll runs) sees the correct value.
$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'Invoke-PiHoleFlushNetwork (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

# Recomputed here (not read from the discovery-time $script:ConfigAvailable above) because
# Pester runs discovery and run in separate scopes, so BeforeAll cannot see that value.
$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@

# Config availability must be known at discovery time so the -Skip parameter on each It block
# (evaluated during discovery, before BeforeAll runs) sees the correct value.
$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'Restart-PiHoleDnsService (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

# Recomputed here (not read from the discovery-time $script:ConfigAvailable above) because
# Pester runs discovery and run in separate scopes, so BeforeAll cannot see that value.
$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@

# Config availability must be known at discovery time so the -Skip parameter on each It block
# (evaluated during discovery, before BeforeAll runs) sees the correct value.
$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'Update-PiHoleActionsGravity (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

# Recomputed here (not read from the discovery-time $script:ConfigAvailable above) because
# Pester runs discovery and run in separate scopes, so BeforeAll cannot see that value.
$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically
# if that file is missing.

$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'Get-PiHoleCurrentAuthSession (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically
# if that file is missing.

$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'Get-PiHoleConfig (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically
# if that file is missing.

$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'Get-PiHoleDnsBlockingStatus (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically
# if that file is missing.

$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'Get-PiHoleInfoHost (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically
# if that file is missing.

$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'Get-PiHoleInfoMessage (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically
# if that file is missing.

$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'Get-PiHoleGroup (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically
# if that file is missing.

$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'New-PiHoleGroup (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

$script:TestGroupName = 'PesterGroup'

$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically
# if that file is missing.

$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'Remove-PiHoleGroup (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

$script:TestGroupName = 'PesterGroup'

$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically
# if that file is missing.

$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'Update-PiHoleGroup (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

$script:TestGroupName = 'PesterGroup'

$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically
# if that file is missing.

$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'Get-PiHoleHistory (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
$script:PiHoleToken = $PiHoleToken
$script:PiHoleIgnoreSsl = $PiHoleIgnoreSsl

# Generates some real query traffic so live history isn't all zero/empty.
& (Join-Path $PSScriptRoot 'Initialize-PiHoleTestData.ps1') -DnsServer $PiHoleServer.Host
& (Join-Path (Split-Path $PSScriptRoot -Parent) 'Initialize-PiHoleTestData.ps1') -DnsServer $PiHoleServer.Host
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically
# if that file is missing.

$script:ConfigAvailable = Test-Path (Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1')
$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1')

Describe 'Get-PiHoleHistoryClient (Integration)' -Tag 'Integration' {
BeforeAll {
Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force

$configPath = Join-Path $PSScriptRoot 'IntegrationConfig.local.ps1'
$configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1'
if (Test-Path $configPath) {
. $configPath
$script:PiHoleServer = $PiHoleServer
$script:PiHoleToken = $PiHoleToken
$script:PiHoleIgnoreSsl = $PiHoleIgnoreSsl

# Generates some real query traffic so live client history isn't all zero/empty.
& (Join-Path $PSScriptRoot 'Initialize-PiHoleTestData.ps1') -DnsServer $PiHoleServer.Host
& (Join-Path (Split-Path $PSScriptRoot -Parent) 'Initialize-PiHoleTestData.ps1') -DnsServer $PiHoleServer.Host
}
}

Expand Down
Loading
Loading