Microsoft365DSC/Tests/QA/Microsoft365DSC.Examples.Te...

231 строка
9.5 KiB
PowerShell

BeforeDiscovery {
$examplesPath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\Microsoft365DSC\Examples'
# If there are no Examples folder, exit.
if (-not (Test-Path -Path $examplesPath))
{
return
}
$exampleFiles = @(Get-ChildItem -Path $examplesPath -Filter '*.ps1' -Recurse)
$exampleToTest = @()
foreach ($exampleFile in $exampleFiles)
{
$exampleToTest += @{
ExampleFile = $exampleFile
ExampleDescriptiveName = Join-Path -Path (Split-Path $exampleFile.Directory -Leaf) -ChildPath (Split-Path $exampleFile -Leaf)
ResourceName = Split-Path $exampleFile.Directory -Leaf
}
}
$resourcesPath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\Microsoft365DSC\DscResources'
# If there are no Examples folder, exit.
if (-not (Test-Path -Path $resourcesPath))
{
return
}
$resourceFolders = Get-ChildItem -Path $resourcesPath -Directory
$allResources = @()
foreach ($resourceFolder in $resourceFolders)
{
$allResources += @{
ResourceFolder = $resourceFolder.FullName
ResourceName = $resourceFolder.BaseName -replace '^MSFT_', ''
}
}
}
Describe -Name 'Successfully compile examples' {
BeforeAll {
function Get-PublishFileName
{
[CmdletBinding()]
[OutputType([System.String])]
param
(
[Parameter(Mandatory = $true)]
[System.String]
$Path
)
# Get the filename without extension.
$filenameWithoutExtension = (Get-Item -Path $Path).BaseName
<#
Resource modules using auto-documentation uses a numeric value followed
by a dash ('-') to be able to control the order of the example in
the documentation. That will not be used when publishing, so remove
it here from the name that is compared to the configuration name.
#>
return $filenameWithoutExtension -replace '^[0-9]+-'
}
}
It "Should compile example '<ExampleDescriptiveName>' correctly" -TestCases $exampleToTest {
{
$mockPassword = ConvertTo-SecureString '&iPm%M5q3K$Hhq=wcEK' -AsPlainText -Force
$mockCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @('tenantadmin@contoso.onmicrosoft.com', $mockPassword)
$mockConfigurationData = @{
AllNodes = @(
@{
NodeName = 'localhost'
PsDscAllowPlainTextPassword = $true
}
)
}
<#
Set this first because it is used in the final block,
and must be set otherwise it fails on not being assigned.
#>
$existingCommandName = $null
try
{
. $ExampleFile.FullName
<#
Test for either a configuration named 'Example',
or parse the name from the filename and try that
as the configuration name (requirement for Azure
Automation).
#>
$commandName = @(
'Example',
(Get-PublishFileName -Path $ExampleFile.FullName)
)
# Get the first one that matches.
$existingCommand = Get-ChildItem -Path 'function:' | Where-Object {
$_.Name -in $commandName
} | Select-Object -First 1
if ($existingCommand)
{
$existingCommandName = $existingCommand.Name
$exampleCommand = Get-Command -Name $existingCommandName -ErrorAction 'SilentlyContinue'
if ($exampleCommand)
{
$exampleParameters = @{}
# Remove any common parameters that are available.
$commandParameters = $exampleCommand.Parameters.Keys | Where-Object -FilterScript {
($_ -notin [System.Management.Automation.PSCmdlet]::CommonParameters) -and `
($_ -notin [System.Management.Automation.PSCmdlet]::OptionalCommonParameters)
}
foreach ($parameterName in $commandParameters)
{
$parameterType = $exampleCommand.Parameters[$parameterName].ParameterType.FullName
<#
Each credential parameter in the Example function is assigned the
mocked credential. 'PsDscRunAsCredential' is not assigned because
that breaks the example.
#>
if ($parameterName -ne 'PsDscRunAsCredential' `
-and $parameterType -eq 'System.Management.Automation.PSCredential')
{
$exampleParameters.Add($parameterName, $mockCredential)
}
else
{
<#
Check for mandatory parameters.
Assume the parameters are all in the 'all' parameter set.
#>
$isParameterMandatory = $exampleCommand.Parameters[$parameterName].ParameterSets['__AllParameterSets'].IsMandatory
if ($isParameterMandatory)
{
<#
Convert '1' to the type that the parameter expects.
Using '1' since it can be converted to String, Numeric
and Boolean.
#>
$exampleParameters.Add($parameterName, ('1' -as $parameterType))
}
elseif ($parameterName -eq 'TenantId')
{
$exampleParameters.Add('TenantId', (New-Guid).ToString())
}
}
}
<#
If there is a $ConfigurationData variable that was dot-sourced
then use that as the configuration data instead of the mocked
configuration data.
#>
if (Get-Item -Path variable:ConfigurationData -ErrorAction 'SilentlyContinue')
{
$mockConfigurationData = $ConfigurationData
}
& $exampleCommand.Name @exampleParameters -ConfigurationData $mockConfigurationData -OutputPath 'TestDrive:\' -ErrorAction 'Continue' -WarningAction 'SilentlyContinue' | Out-Null
}
}
else
{
throw ('The example ''{0}'' does not contain a configuration named ''{1}''.' -f $exampleDescriptiveName, ($commandName -join "', or '"))
}
}
finally
{
<#
Remove the function we dot-sourced so next example file
doesn't use the previous Example-function. Using recurse
since it saw child functions when copied in helper functions
during debugging, it resulted in an interactive prompt.
#>
Remove-Item -Path "function:$existingCommandName" -ErrorAction 'SilentlyContinue' -Recurse -Force
<#
Remove the variable $ConfigurationData if it existed in
the file we dot-sourced so next example file doesn't use
the previous examples configuration.
#>
Remove-Item -Path 'variable:ConfigurationData' -ErrorAction 'SilentlyContinue'
}
} | Should -Not -Throw
}
}
Describe -Name 'Check examples for all resources' {
BeforeAll {
$examplesPath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\Microsoft365DSC\Examples'
# If there are no Examples folder, exit.
if (-not (Test-Path -Path $examplesPath))
{
return
}
$exampleFiles = @(Get-ChildItem -Path $examplesPath -Filter '*.ps1' -Recurse)
$exampleToTest = @()
foreach ($exampleFile in $exampleFiles)
{
$exampleToTest += @{
ExampleFile = $exampleFile
ExampleDescriptiveName = Join-Path -Path (Split-Path $exampleFile.Directory -Leaf) -ChildPath (Split-Path $exampleFile -Leaf)
ResourceName = Split-Path $exampleFile.Directory -Leaf
}
}
}
It "An example for '<ResourceName>' should exist" -TestCases $allResources {
[Array]$res = $exampleToTest | Where-Object -FilterScript { $_.ResourceName -eq $ResourceName }
$res.Count | Should -BeGreaterOrEqual 1
}
}