From 20ac8b7116cf7781600646dc0d5d85dcdae0df45 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Tue, 7 Nov 2023 22:23:26 +0100 Subject: [PATCH 01/52] Added skeleton --- .../compliance/module.tests.ps1 | 272 ++++++++++++------ 1 file changed, 185 insertions(+), 87 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 700771fe11..c1a0174819 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -3,7 +3,7 @@ param ( [Parameter(Mandatory = $false)] [array] $moduleFolderPaths = ((Get-ChildItem $repoRootPath -Recurse -Directory -Force).FullName | Where-Object { - (Get-ChildItem $_ -File -Depth 0 -Include @('main.json', 'main.bicep') -Force).Count -gt 0 + (Get-ChildItem $_ -File -Depth 0 -Include @('main.bicep') -Force).Count -gt 0 }), [Parameter(Mandatory = $false)] @@ -27,7 +27,6 @@ $script:convertedTemplates = @{} # Shared exception messages $script:bicepTemplateCompilationFailedException = "Unable to compile the main.bicep template's content. This can happen if there is an error in the template. Please check if you can run the command ``bicep build {0} --stdout | ConvertFrom-Json -AsHashtable``." # -f $templateFilePath -$script:jsonTemplateLoadFailedException = "Unable to load the main.json template's content. This can happen if there is an error in the template. Please check if you can run the command `Get-Content {0} -Raw | ConvertFrom-Json -AsHashtable`." # -f $templateFilePath $script:templateNotFoundException = 'No template file found in folder [{0}]' # -f $moduleFolderPath # Import any helper function used in this test script @@ -203,24 +202,14 @@ Describe 'Module tests' -Tag 'Module' { if (-not $templateContent) { throw ($bicepTemplateCompilationFailedException -f $templateFilePath) } - } - elseIf (Test-Path (Join-Path $moduleFolderPath 'main.json')) { - $templateFilePath = Join-Path $moduleFolderPath 'main.json' - $templateContent = Get-Content $templateFilePath -Raw | ConvertFrom-Json -AsHashtable - - if (-not $templateContent) { - throw ($jsonTemplateLoadFailedException -f $templateFilePath) - } - } - else { + } else { throw ($templateNotFoundException -f $moduleFolderPath) } $convertedTemplates[$moduleFolderPathKey] = @{ templateFilePath = $templateFilePath templateContent = $templateContent } - } - else { + } else { $templateContent = $convertedTemplates[$moduleFolderPathKey].templateContent $templateFilePath = $convertedTemplates[$moduleFolderPathKey].templateFilePath } @@ -342,24 +331,14 @@ Describe 'Module tests' -Tag 'Module' { if (-not $templateContent) { throw ($bicepTemplateCompilationFailedException -f $templateFilePath) } - } - elseIf (Test-Path (Join-Path $moduleFolderPath 'main.json')) { - $templateFilePath = Join-Path $moduleFolderPath 'main.json' - $templateContent = Get-Content $templateFilePath -Raw | ConvertFrom-Json -AsHashtable - - if (-not $templateContent) { - throw ($jsonTemplateLoadFailedException -f $templateFilePath) - } - } - else { + } else { throw ($templateNotFoundException -f $moduleFolderPath) } $convertedTemplates[$moduleFolderPathKey] = @{ templateFilePath = $templateFilePath templateContent = $templateContent } - } - else { + } else { $templateContent = $convertedTemplates[$moduleFolderPathKey].templateContent $templateFilePath = $convertedTemplates[$moduleFolderPathKey].templateFilePath } @@ -423,17 +402,13 @@ Describe 'Module tests' -Tag 'Module' { $SchemaArray = @() if ($Schemaverion -eq $RgDeploymentSchema) { $SchemaOutput = $true - } - elseIf ($Schemaverion -eq $SubscriptionDeploymentSchema) { + } elseIf ($Schemaverion -eq $SubscriptionDeploymentSchema) { $SchemaOutput = $true - } - elseIf ($Schemaverion -eq $MgDeploymentSchema) { + } elseIf ($Schemaverion -eq $MgDeploymentSchema) { $SchemaOutput = $true - } - elseIf ($Schemaverion -eq $TenantDeploymentSchema) { + } elseIf ($Schemaverion -eq $TenantDeploymentSchema) { $SchemaOutput = $true - } - else { + } else { $SchemaOutput = $false } $SchemaArray += $SchemaOutput @@ -496,8 +471,7 @@ Describe 'Module tests' -Tag 'Module' { foreach ($Param in $Parameter) { if ($Param.substring(0, 1) -cnotmatch '[a-z]' -or $Param -match '-' -or $Param -match '_') { $CamelCasingFlag += $false - } - else { + } else { $CamelCasingFlag += $true } } @@ -522,8 +496,7 @@ Describe 'Module tests' -Tag 'Module' { foreach ($Variab in $Variable) { if ($Variab.substring(0, 1) -cnotmatch '[a-z]' -or $Variab -match '-') { $CamelCasingFlag += $false - } - else { + } else { $CamelCasingFlag += $true } } @@ -542,8 +515,7 @@ Describe 'Module tests' -Tag 'Module' { foreach ($Output in $Outputs) { if ($Output.substring(0, 1) -cnotmatch '[a-z]' -or $Output -match '-' -or $Output -match '_') { $CamelCasingFlag += $false - } - else { + } else { $CamelCasingFlag += $true } } @@ -560,8 +532,7 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } - else { + } else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -579,8 +550,7 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } - else { + } else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -604,8 +574,7 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } - else { + } else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -634,8 +603,7 @@ Describe 'Module tests' -Tag 'Module' { if ($Locationparamoutput -contains 'Location') { if ($Locationparamoutputvalue -eq '[resourceGroup().Location]' -or $Locationparamoutputvalue -eq 'global') { $LocationFlag = $true - } - else { + } else { $LocationFlag = $false } @@ -696,8 +664,7 @@ Describe 'Module tests' -Tag 'Module' { $readMeFileContentHeader = (Get-Content -Path $readMeFilePath)[0] if ($readMeFileContentHeader -match '^.*`\[(.+)\]`.*') { $primaryResourceType = $matches[1] - } - else { + } else { Write-Error "Cannot identity primary resource type in readme header [$readMeFileContentHeader] and cannot execute the test." return } @@ -705,8 +672,7 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } - else { + } else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -732,8 +698,7 @@ Describe 'Module tests' -Tag 'Module' { $readMeFileContentHeader = (Get-Content -Path $readMeFilePath)[0] if ($readMeFileContentHeader -match '^.*`\[(.+)\]`.*') { $primaryResourceType = $matches[1] - } - else { + } else { Write-Error "Cannot identity primary resource type in readme header [$readMeFileContentHeader] and cannot execute the test." return } @@ -741,8 +706,7 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } - else { + } else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -856,7 +820,6 @@ Describe 'Module tests' -Tag 'Module' { $incorrectOutputs | Should -BeNullOrEmpty } - # Update to work with nullable parameters It '[] All non-required parameters in template file should not have description that start with "Required.".' -TestCases $deploymentFolderTestCases { param ( [hashtable[]] $testFileTestCases, @@ -895,23 +858,13 @@ Describe 'Module tests' -Tag 'Module' { if (-not $templateContent) { throw ($bicepTemplateCompilationFailedException -f $templateFilePath) } - } - elseIf (Test-Path (Join-Path $moduleFolderPath 'main.json')) { - $templateFilePath = Join-Path $moduleFolderPath 'main.json' - $templateContent = Get-Content $templateFilePath -Raw | ConvertFrom-Json -AsHashtable - - if (-not $templateContent) { - throw ($jsonTemplateLoadFailedException -f $templateFilePath) - } - } - else { + } else { throw ($templateNotFoundException -f $moduleFolderPath) } $convertedTemplates[$moduleFolderPathKey] = @{ templateContent = $templateContent } - } - else { + } else { $templateContent = $convertedTemplates[$moduleFolderPathKey].templateContent } @@ -954,6 +907,96 @@ Describe 'Module tests' -Tag 'Module' { $templateFileContent.metadata.owner | Should -Not -BeNullOrEmpty } } + + Context 'User-defined-types tests' -Tag 'UDT' { + + $udtTestCases = [System.Collections.ArrayList] @() + foreach ($moduleFolderPath in $moduleFolderPaths) { + + $resourceTypeIdentifier = ($moduleFolderPath -split '[\/|\\]{1}avm[\/|\\]{1}(res|ptn)[\/|\\]{1}')[2] -replace '\\', '/' # avm/res// + + # For runtime purposes, we cache the compiled template in a hashtable that uses a formatted relative module path as a key + $moduleFolderPathKey = $moduleFolderPath.Replace('\', '/').Split('/avm/')[1].Trim('/').Replace('/', '-') + if (-not ($convertedTemplates.Keys -contains $moduleFolderPathKey)) { + if (Test-Path (Join-Path $moduleFolderPath 'main.bicep')) { + $templateFilePath = Join-Path $moduleFolderPath 'main.bicep' + $templateContent = bicep build $templateFilePath --stdout | ConvertFrom-Json -AsHashtable + + if (-not $templateContent) { + throw ($bicepTemplateCompilationFailedException -f $templateFilePath) + } + } else { + throw ($templateNotFoundException -f $moduleFolderPath) + } + $convertedTemplates[$moduleFolderPathKey] = @{ + templateContent = $templateContent + } + } else { + $templateContent = $convertedTemplates[$moduleFolderPathKey].templateContent + } + + $udtTestCases += @{ + moduleFolderName = $resourceTypeIdentifier + templateFileContent = $templateContent + } + } + + + It "[] If template has [roleAssignments] parameter, it should implement the expected user-defined-type" -TestCases $udtTestCases { + + param( + [object[]] $templateFileContent + ) + throw 'Not implemented' + + } + + It "[] If template has [privateEndpoints] parameter, it should implement the expected user-defined-type" -TestCases $udtTestCases { + + param( + [object[]] $templateFileContent + ) + throw 'Not implemented' + + } + + It "[] If template has [diagnosticSettings] parameter, it should implement the expected user-defined-type" -TestCases $udtTestCases { + + param( + [object[]] $templateFileContent + ) + throw 'Not implemented' + + } + + It "[] If template has [lock] parameter, it should implement the expected user-defined-type" -TestCases $udtTestCases { + + param( + [object[]] $templateFileContent + ) + throw 'Not implemented' + + } + + It "[] If template has [customerManagedKey] parameter, it should implement the expected user-defined-type" -TestCases $udtTestCases { + + param( + [object[]] $templateFileContent + ) + throw 'Not implemented' + + } + + It "[] If template has [diagnosticSettings] parameter, it should implement the expected user-defined-type" -TestCases $udtTestCases { + + param( + [object[]] $templateFileContent + ) + throw 'Not implemented' + + } + + } } Describe 'Test file tests' -Tag 'TestTemplate' { @@ -978,6 +1021,74 @@ Describe 'Test file tests' -Tag 'TestTemplate' { } } + It "[] Bicep test deployment files should contain serviceShort parameter" -TestCases $deploymentTestFileTestCases { + + param( + [object[]] $testFileContent + ) + throw 'Not implemented' + + } + + It "[] Bicep test deployment files in a [default] folder should contain a service short with ending [min]" -TestCases $deploymentTestFileTestCases { + + param( + [string] $testFilePath, + [object[]] $testFileContent + ) + #TODO: must consider that the folder name is more than just 'default' + throw 'Not implemented' + + } + + It "[] Bicep test deployment files in a [max] folder should contain a service short with ending [max]" -TestCases $deploymentTestFileTestCases { + + param( + [string] $testFilePath, + [object[]] $testFileContent + ) + #TODO: must consider that the folder name is more than just 'max' + throw 'Not implemented' + + } + + It "[] Bicep test deployment files in a [waf-aligned] folder should contain a service short with ending [waf]" -TestCases $deploymentTestFileTestCases { + + param( + [string] $testFilePath, + [object[]] $testFileContent + ) + #TODO: must consider that the folder name is more than just 'waf' + throw 'Not implemented' + + } + + It "[] Bicep test deployment files should contain a test name" -TestCases $deploymentTestFileTestCases { + + param( + [object[]] $testFileContent + ) + throw 'Not implemented' + + } + + It "[] Bicep test deployment files should contain a test description" -TestCases $deploymentTestFileTestCases { + + param( + [object[]] $testFileContent + ) + throw 'Not implemented' + + } + + It "[] Bicep test deployment files should contain namePrefix parameter with value ['#_namePrefix_#']" -TestCases $deploymentTestFileTestCases { + + param( + [object[]] $testFileContent + ) + throw 'Not implemented' + } + It "[] Bicep test deployment files should invoke test like [`module testDeployment '../.*main.bicep' = {`]" -TestCases $deploymentTestFileTestCases { param( @@ -1021,8 +1132,7 @@ Describe 'API version tests' -Tag 'ApiCheck' { try { $apiSpecs = Invoke-WebRequest -Uri $ApiSpecsFileUri $ApiVersions = ConvertFrom-Json $apiSpecs.Content -AsHashtable - } - catch { + } catch { Write-Warning "Failed to download API specs file from [$ApiSpecsFileUri]. Skipping API tests" Set-ItResult -Skipped -Because "Failed to download API specs file from [$ApiSpecsFileUri]. Skipping API tests." return @@ -1042,24 +1152,14 @@ Describe 'API version tests' -Tag 'ApiCheck' { if (-not $templateContent) { throw ($bicepTemplateCompilationFailedException -f $templateFilePath) } - } - elseIf (Test-Path (Join-Path $moduleFolderPath 'main.json')) { - $templateFilePath = Join-Path $moduleFolderPath 'main.json' - $templateContent = Get-Content $templateFilePath -Raw | ConvertFrom-Json -AsHashtable - - if (-not $templateContent) { - throw ($jsonTemplateLoadFailedException -f $templateFilePath) - } - } - else { + } else { throw ($templateNotFoundException -f $moduleFolderPath) } $convertedTemplates[$moduleFolderPathKey] = @{ templateFilePath = $templateFilePath templateContent = $templateContent } - } - else { + } else { $templateContent = $convertedTemplates[$moduleFolderPathKey].templateContent $templateFilePath = $convertedTemplates[$moduleFolderPathKey].templateFilePath } @@ -1165,8 +1265,7 @@ Describe 'API version tests' -Tag 'ApiCheck' { # We allow the latest 5 including previews (in case somebody wants to use preview), or the latest 3 non-preview $approvedApiVersions += $resourceTypeApiVersions | Select-Object -Last 5 $approvedApiVersions += $resourceTypeApiVersions | Where-Object { $_ -notlike '*-preview' } | Select-Object -Last 5 - } - else { + } else { # We allow the latest 5 non-preview preview $approvedApiVersions += $resourceTypeApiVersions | Where-Object { $_ -notlike '*-preview' } | Select-Object -Last 5 } @@ -1179,8 +1278,7 @@ Describe 'API version tests' -Tag 'ApiCheck' { # The original failed test was # $approvedApiVersions | Should -Contain $TargetApi - } - else { + } else { # Provide a warning if an API version is second to next to expire. $indexOfVersion = $approvedApiVersions.IndexOf($TargetApi) From 4939b4d2e85ac2db8d8b2a67cb17fac7363196c7 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 00:38:44 +0100 Subject: [PATCH 02/52] Implemented first new tests --- avm/res/key-vault/vault/main.bicep | 3 - avm/res/key-vault/vault/main.json | 26 +-- .../compliance/module.tests.ps1 | 148 +++++++++++------- 3 files changed, 103 insertions(+), 74 deletions(-) diff --git a/avm/res/key-vault/vault/main.bicep b/avm/res/key-vault/vault/main.bicep index ae038cf1f5..4e62950d9c 100644 --- a/avm/res/key-vault/vault/main.bicep +++ b/avm/res/key-vault/vault/main.bicep @@ -353,9 +353,6 @@ type roleAssignmentType = { @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container"') condition: string? - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - @description('Optional. The Resource Id of the delegated managed identity resource.') delegatedManagedIdentityResourceId: string? }[]? diff --git a/avm/res/key-vault/vault/main.json b/avm/res/key-vault/vault/main.json index f10c40c0fb..bfcfb41b93 100644 --- a/avm/res/key-vault/vault/main.json +++ b/avm/res/key-vault/vault/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "9188769706526490100" + "version": "0.23.1.45101", + "templateHash": "8353941507512521049" }, "name": "Key Vaults", "description": "This module deploys a Key Vault.", @@ -164,16 +164,6 @@ "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" } }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, "delegatedManagedIdentityResourceId": { "type": "string", "nullable": true, @@ -682,8 +672,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "9999250509448584761" + "version": "0.23.1.45101", + "templateHash": "4111939022872407830" }, "name": "Key Vault Access Policies", "description": "This module deploys a Key Vault Access Policy.", @@ -815,8 +805,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "11139788551431901948" + "version": "0.23.1.45101", + "templateHash": "9180551172362989336" }, "name": "Key Vault Secrets", "description": "This module deploys a Key Vault Secret.", @@ -1104,8 +1094,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "15591839680984542683" + "version": "0.23.1.45101", + "templateHash": "2691621623448325959" }, "name": "Key Vault Keys", "description": "This module deploys a Key Vault Key.", diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index c1a0174819..f3ab52891e 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -935,67 +935,109 @@ Describe 'Module tests' -Tag 'Module' { $templateContent = $convertedTemplates[$moduleFolderPathKey].templateContent } - $udtTestCases += @{ - moduleFolderName = $resourceTypeIdentifier - templateFileContent = $templateContent - } - } - - - It "[] If template has [roleAssignments] parameter, it should implement the expected user-defined-type" -TestCases $udtTestCases { - - param( - [object[]] $templateFileContent + # Setting expected URL only for those that doen't have multiple different variants + $avmInterfaceSpecsBase = 'https://raw.githubusercontent.com/Azure/Azure-Verified-Modules/main/docs/static/includes/interfaces' + $udtCases = @( + @{ + parameterName = 'diagnosticSettings' + udtName = 'diagnosticSettingType' + } + @{ + parameterName = 'roleAssignments' + udtName = 'roleAssignmentType' + udtExpectedUrl = "$avmInterfaceSpecsBase/int.rbac.udt.schema.bicep" + } + @{ + parameterName = 'lock' + udtName = 'lockType' + udtExpectedUrl = "$avmInterfaceSpecsBase/int.locks.udt.schema.bicep" + } + @{ + parameterName = 'managedIdentities' + udtName = 'managedIdentitiesType' + } + @{ + parameterName = 'privateEndpoints' + udtName = 'privateEndpointType' + } + @{ + parameterName = 'customerManagedKey' + udtName = 'customerManagedKeyType' + } ) - throw 'Not implemented' + foreach ($udtCase in $udtCases) { + $udtTestCases += @{ + moduleFolderName = $resourceTypeIdentifier + templateFileContent = $templateContent + templateFileContentBicep = Get-Content $templateFilePath + parameterName = $udtCase.parameterName + udtName = $udtCase.udtName + expectedUdtUrl = $udtCase.udtExpectedUrl ? $udtCase.udtExpectedUrl : '' + } + } } - It "[] If template has [privateEndpoints] parameter, it should implement the expected user-defined-type" -TestCases $udtTestCases { - param( - [object[]] $templateFileContent - ) - throw 'Not implemented' - - } - - It "[] If template has [diagnosticSettings] parameter, it should implement the expected user-defined-type" -TestCases $udtTestCases { + It "[] If template has [] parameter, it should implement the expected user-defined type []" -TestCases $udtTestCases { param( - [object[]] $templateFileContent + [hashtable] $templateFileContent, + [string[]] $templateFileContentBicep, + [string] $parameterName, + [string] $udtName, + [string] $expectedUdtUrl ) - throw 'Not implemented' - - } - It "[] If template has [lock] parameter, it should implement the expected user-defined-type" -TestCases $udtTestCases { + if ($templateFileContent.parameters.Keys -contains $parameterName) { + $templateFileContent.parameters.$parameterName.Keys | Should -Contain '$ref' -Because "the [$parameterName] parameter should use a user-defined type." + $templateFileContent.parameters.$parameterName.'$ref' | Should -Be "#/definitions/$udtName" -Because "the [$parameterName] parameter should use a user-defined type [$udtName]." - param( - [object[]] $templateFileContent - ) - throw 'Not implemented' - - } - - It "[] If template has [customerManagedKey] parameter, it should implement the expected user-defined-type" -TestCases $udtTestCases { + if (-not [String]::IsNullOrEmpty($expectedUdtUrl)) { + $implementedSchemaStartIndex = $templateFileContentBicep.IndexOf("type $udtName = {") + $implementedSchemaEndIndex = $implementedSchemaStartIndex + 1 + while ($templateFileContentBicep[$implementedSchemaEndIndex] -notmatch '^\}.*' -and $implementedSchemaEndIndex -lt $templateFileContentBicep.Length) { + $implementedSchemaEndIndex++ + } + if ($implementedSchemaEndIndex -eq $templateFileContentBicep.Length) { + throw "Failed to identify [$udtName] user-defined type in template." + } + $implementedSchema = $templateFileContentBicep[$implementedSchemaStartIndex..$implementedSchemaEndIndex] - param( - [object[]] $templateFileContent - ) - throw 'Not implemented' + $expectedSchemaFull = (Invoke-WebRequest -Uri $expectedUdtUrl).Content -split "\n" + $expectedSchemaStartIndex = $expectedSchemaFull.IndexOf("type $udtName = {") + $expectedSchemaEndIndex = $expectedSchemaStartIndex + 1 + while ($expectedSchemaFull[$expectedSchemaEndIndex] -notmatch '^\}.*' -and $expectedSchemaEndIndex -lt $expectedSchemaFull.Length) { + $expectedSchemaEndIndex++ + } + if ($expectedSchemaEndIndex -eq $expectedSchemaFull.Length) { + throw "Failed to identify [$udtName] user-defined type in expected schema at URL [$expectedUdtUrl]." + } + $expectedSchema = $expectedSchemaFull[$expectedSchemaStartIndex..$expectedSchemaEndIndex] + + $formattedDiff = @() + foreach ($finding in (Compare-Object $implementedSchema $expectedSchema)) { + if ($finding.SideIndicator -eq '=>') { + $formattedDiff += ('+ {0}' -f $finding.InputObject) + } elseif ($finding.SideIndicator -eq '<=') { + $formattedDiff += ('- {0}' -f $finding.InputObject) + } + } + if ($formattedDiff.Count -gt 0) { + Write-Warning ($formattedDiff | Out-String) -Verbose + $mdFormattedDiff = ($formattedDiff -join '
') -replace '\|', '\|' + } + ($implementedSchema | Out-String) | Should -Be ($expectedSchema | Out-String) -Because ('The implemented user-defined type should be the same as the expected user-defined type of url [{0}] and should not have diff
{1}
.' -f $expectedUdtUrl, $mdFormattedDiff) + } + } else { + Set-ItResult -Skipped -Because "the module template has no [$parameterName] parameter." + } } - It "[] If template has [diagnosticSettings] parameter, it should implement the expected user-defined-type" -TestCases $udtTestCases { - - param( - [object[]] $templateFileContent - ) - throw 'Not implemented' - - } + # TODO Add test for tags + # TODO add tests for msi principal id output } } @@ -1026,7 +1068,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { param( [object[]] $testFileContent ) - throw 'Not implemented' + Write-Error 'Not implemented' } @@ -1037,7 +1079,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { [object[]] $testFileContent ) #TODO: must consider that the folder name is more than just 'default' - throw 'Not implemented' + Write-Error 'Not implemented' } @@ -1048,7 +1090,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { [object[]] $testFileContent ) #TODO: must consider that the folder name is more than just 'max' - throw 'Not implemented' + Write-Error 'Not implemented' } @@ -1059,7 +1101,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { [object[]] $testFileContent ) #TODO: must consider that the folder name is more than just 'waf' - throw 'Not implemented' + Write-Error 'Not implemented' } @@ -1068,7 +1110,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { param( [object[]] $testFileContent ) - throw 'Not implemented' + Write-Error 'Not implemented' } @@ -1077,7 +1119,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { param( [object[]] $testFileContent ) - throw 'Not implemented' + Write-Error 'Not implemented' } @@ -1086,7 +1128,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { param( [object[]] $testFileContent ) - throw 'Not implemented' + Write-Error 'Not implemented' } It "[] Bicep test deployment files should invoke test like [`module testDeployment '../.*main.bicep' = {`]" -TestCases $deploymentTestFileTestCases { From 4e1d86f3848f9aa4e858f834bb373af04d64c179 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 09:19:19 +0100 Subject: [PATCH 03/52] Changed to warning --- .../pipelines/staticValidation/compliance/module.tests.ps1 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index f3ab52891e..dd9c9fb5e1 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -1023,12 +1023,10 @@ Describe 'Module tests' -Tag 'Module' { $formattedDiff += ('- {0}' -f $finding.InputObject) } } + if ($formattedDiff.Count -gt 0) { - Write-Warning ($formattedDiff | Out-String) -Verbose - $mdFormattedDiff = ($formattedDiff -join '
') -replace '\|', '\|' + Write-Warning ("The implemented user-defined type should be the same as the expected user-defined type of url [{0}] and should not have diff`n{1}" -f $expectedUdtUrl, ($formattedDiff | Out-String)) } - - ($implementedSchema | Out-String) | Should -Be ($expectedSchema | Out-String) -Because ('The implemented user-defined type should be the same as the expected user-defined type of url [{0}] and should not have diff
{1}
.' -f $expectedUdtUrl, $mdFormattedDiff) } } else { Set-ItResult -Skipped -Because "the module template has no [$parameterName] parameter." From 94fff0ba27001ed731cd18daee02d1b06b7cef21 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 14:19:32 +0100 Subject: [PATCH 04/52] Expanded test verbosity & added additional tets --- .../compliance/module.tests.ps1 | 59 +++++++++++++++---- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index dd9c9fb5e1..cc36fb716e 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -910,7 +910,8 @@ Describe 'Module tests' -Tag 'Module' { Context 'User-defined-types tests' -Tag 'UDT' { - $udtTestCases = [System.Collections.ArrayList] @() + $udtTestCases = [System.Collections.ArrayList] @() # General UDT tests (e.g. param should exist) + $udtSpecificTestCases = [System.Collections.ArrayList] @() # Specific UDT test cases for singular UDTs (e.g. tags) foreach ($moduleFolderPath in $moduleFolderPaths) { $resourceTypeIdentifier = ($moduleFolderPath -split '[\/|\\]{1}avm[\/|\\]{1}(res|ptn)[\/|\\]{1}')[2] -replace '\\', '/' # avm/res// @@ -935,34 +936,47 @@ Describe 'Module tests' -Tag 'Module' { $templateContent = $convertedTemplates[$moduleFolderPathKey].templateContent } + $udtSpecificTestCases += @{ + moduleFolderName = $resourceTypeIdentifier + templateFileContent = $templateContent + templateFileContentBicep = Get-Content $templateFilePath + } + # Setting expected URL only for those that doen't have multiple different variants - $avmInterfaceSpecsBase = 'https://raw.githubusercontent.com/Azure/Azure-Verified-Modules/main/docs/static/includes/interfaces' + $avmInterfaceSpecsTemplateBase = 'https://raw.githubusercontent.com/Azure/Azure-Verified-Modules/main/docs/static/includes/interfaces' + $avmInterfaceSpecsBase = 'https://azure.github.io/Azure-Verified-Modules/specs/shared/interfaces' $udtCases = @( @{ parameterName = 'diagnosticSettings' udtName = 'diagnosticSettingType' + link = "$avmInterfaceSpecsBase#diagnostic-settings" } @{ parameterName = 'roleAssignments' udtName = 'roleAssignmentType' - udtExpectedUrl = "$avmInterfaceSpecsBase/int.rbac.udt.schema.bicep" + udtExpectedUrl = "$avmInterfaceSpecsTemplateBase/int.rbac.udt.schema.bicep" + link = "$avmInterfaceSpecsBase#role-assignments" } @{ parameterName = 'lock' udtName = 'lockType' - udtExpectedUrl = "$avmInterfaceSpecsBase/int.locks.udt.schema.bicep" + udtExpectedUrl = "$avmInterfaceSpecsTemplateBase/int.locks.udt.schema.bicep" + link = "$avmInterfaceSpecsBase#resource-locks" } @{ parameterName = 'managedIdentities' udtName = 'managedIdentitiesType' + link = "$avmInterfaceSpecsBase#managed-identities" } @{ parameterName = 'privateEndpoints' udtName = 'privateEndpointType' + link = "$avmInterfaceSpecsBase#private-endpoints" } @{ parameterName = 'customerManagedKey' udtName = 'customerManagedKeyType' + link = "$avmInterfaceSpecsBase#customer-managed-keys" } ) @@ -979,19 +993,20 @@ Describe 'Module tests' -Tag 'Module' { } - It "[] If template has [] parameter, it should implement the expected user-defined type []" -TestCases $udtTestCases { + It "[] If template has [] parameter, it should implement the user-defined type []" -TestCases $udtTestCases { param( [hashtable] $templateFileContent, [string[]] $templateFileContentBicep, [string] $parameterName, [string] $udtName, - [string] $expectedUdtUrl + [string] $expectedUdtUrl, + [string] $link ) if ($templateFileContent.parameters.Keys -contains $parameterName) { - $templateFileContent.parameters.$parameterName.Keys | Should -Contain '$ref' -Because "the [$parameterName] parameter should use a user-defined type." - $templateFileContent.parameters.$parameterName.'$ref' | Should -Be "#/definitions/$udtName" -Because "the [$parameterName] parameter should use a user-defined type [$udtName]." + $templateFileContent.parameters.$parameterName.Keys | Should -Contain '$ref' -Because "the [$parameterName] parameter should use a user-defined type. For for information please review the [AVM Specs]($link)." + $templateFileContent.parameters.$parameterName.'$ref' | Should -Be "#/definitions/$udtName" -Because "the [$parameterName] parameter should use a user-defined type [$udtName]. For for information please review the [AVM Specs]($link)." if (-not [String]::IsNullOrEmpty($expectedUdtUrl)) { $implementedSchemaStartIndex = $templateFileContentBicep.IndexOf("type $udtName = {") @@ -1025,7 +1040,7 @@ Describe 'Module tests' -Tag 'Module' { } if ($formattedDiff.Count -gt 0) { - Write-Warning ("The implemented user-defined type should be the same as the expected user-defined type of url [{0}] and should not have diff`n{1}" -f $expectedUdtUrl, ($formattedDiff | Out-String)) + Write-Warning ("The implemented user-defined type is not the same as the expected [user-defined type]({0}) defined in the [AVM specs]({1}) and should not have diff`n{2}" -f $expectedUdtUrl, $link, ($formattedDiff | Out-String)) } } } else { @@ -1033,9 +1048,31 @@ Describe 'Module tests' -Tag 'Module' { } } + It "[] If a [managedIdentitiesType] UDT definition exists and supports system-assigned-identities, the template should have an output for its principal ID." -TestCases $udtSpecificTestCases { + + param( + [hashtable] $templateFileContent + ) + + if ($templateFileContent.definitions.Keys -contains 'managedIdentitiesType' -and $templateFileContent.definitions.managedIdentitiesType.properties.keys -contains 'systemAssigned') { + $templateFileContent.outputs.Keys | Should -Contain 'systemAssignedMIPrincipalId' -Because 'The AVM specs require a this output. For for information please review the [AVM Specs](https://azure.github.io/Azure-Verified-Modules/specs/shared/interfaces#managed-identities).' + } else { + Set-ItResult -Skipped -Because "the module template has no [managedIdentitiesType] UDT definition or does not support system-assigned-identities." + } + } + + It "[] If a [tags] parameter exists it should be nullable." -TestCases $udtTestCases { - # TODO Add test for tags - # TODO add tests for msi principal id output + param( + [hashtable] $templateFileContent + ) + + if ($templateFileContent.parameters.Keys -contains 'tags') { + $templateFileContent.parameters.tags.nullable | Should -Be $true -Because 'The AVM specs require a specific format. For for information please review the [AVM Specs](https://azure.github.io/Azure-Verified-Modules/specs/shared/interfaces#tags).' + } else { + Set-ItResult -Skipped -Because "the module template has no [tags] parameter." + } + } } } From c18ce6baea39a873b231c956c2439b3913935dc1 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 15:45:41 +0100 Subject: [PATCH 05/52] Finalized further tests --- .../compliance/module.tests.ps1 | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index cc36fb716e..24dbbc5c5f 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -1061,7 +1061,7 @@ Describe 'Module tests' -Tag 'Module' { } } - It "[] If a [tags] parameter exists it should be nullable." -TestCases $udtTestCases { + It "[] If a [tags] parameter exists it should be nullable." -TestCases $udtSpecificTestCases { param( [hashtable] $templateFileContent @@ -1103,41 +1103,49 @@ Describe 'Test file tests' -Tag 'TestTemplate' { param( [object[]] $testFileContent ) - Write-Error 'Not implemented' - + ($testFileContent -match "^param serviceShort string = '(.*)$") | Should -Not -BeNullOrEmpty -Because 'the module test deployment file should contain a service short parameter using the syntax [param serviceShort string = ''*''].' } - It "[] Bicep test deployment files in a [default] folder should contain a service short with ending [min]" -TestCases $deploymentTestFileTestCases { + It "[] Bicep test deployment files in a [default] folder should contain a service short with ending [min]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]defaults[\\|\/].*' }) { param( - [string] $testFilePath, [object[]] $testFileContent ) - #TODO: must consider that the folder name is more than just 'default' - Write-Error 'Not implemented' + if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { + $serviceShort = $Matches[1] + $serviceShort | Should -BeLike "*min" + } else { + Set-ItResult -Skipped -Because 'the module test deployment file should contain a service short parameter using the syntax [param serviceShort string = ''*min''] but it doesn''t.' + } } - It "[] Bicep test deployment files in a [max] folder should contain a service short with ending [max]" -TestCases $deploymentTestFileTestCases { + It "[] Bicep test deployment files in a [max] folder should contain a service short with ending [max]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]max[\\|\/].*' }) { param( - [string] $testFilePath, [object[]] $testFileContent ) - #TODO: must consider that the folder name is more than just 'max' - Write-Error 'Not implemented' + if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { + $serviceShort = $Matches[1] + $serviceShort | Should -BeLike "*max" + } else { + Set-ItResult -Skipped -Because 'the module test deployment file should contain a service short parameter using the syntax [param serviceShort string = ''*max''] but it doesn''t.' + } } - It "[] Bicep test deployment files in a [waf-aligned] folder should contain a service short with ending [waf]" -TestCases $deploymentTestFileTestCases { + It "[] Bicep test deployment files in a [waf-aligned] folder should contain a service short with ending [waf]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]waf\-aligned[\\|\/].*' }) { param( - [string] $testFilePath, [object[]] $testFileContent ) - #TODO: must consider that the folder name is more than just 'waf' - Write-Error 'Not implemented' + if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { + $serviceShort = $Matches[1] + $serviceShort | Should -BeLike "*waf" + } else { + Set-ItResult -Skipped -Because 'the module test deployment file should contain a service short parameter using the syntax [param serviceShort string = ''*waf''] but it doesn''t.' + } } It "[] Bicep test deployment files should contain a test name" -TestCases $deploymentTestFileTestCases { From a3436942147ce7690ab14a9c12ce11f1bc5c628b Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 16:18:05 +0100 Subject: [PATCH 06/52] Update to latest --- .../staticValidation/compliance/module.tests.ps1 | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 24dbbc5c5f..98caa78e5d 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -1113,8 +1113,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { ) if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { - $serviceShort = $Matches[1] - $serviceShort | Should -BeLike "*min" + $Matches[1] | Should -BeLike "*min" } else { Set-ItResult -Skipped -Because 'the module test deployment file should contain a service short parameter using the syntax [param serviceShort string = ''*min''] but it doesn''t.' } @@ -1127,8 +1126,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { ) if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { - $serviceShort = $Matches[1] - $serviceShort | Should -BeLike "*max" + $Matches[1] | Should -BeLike "*max" } else { Set-ItResult -Skipped -Because 'the module test deployment file should contain a service short parameter using the syntax [param serviceShort string = ''*max''] but it doesn''t.' } @@ -1141,8 +1139,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { ) if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { - $serviceShort = $Matches[1] - $serviceShort | Should -BeLike "*waf" + $Matches[1] | Should -BeLike "*waf" } else { Set-ItResult -Skipped -Because 'the module test deployment file should contain a service short parameter using the syntax [param serviceShort string = ''*waf''] but it doesn''t.' } @@ -1153,8 +1150,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { param( [object[]] $testFileContent ) - Write-Error 'Not implemented' - + (($testFileContent | Out-String) -match "metadata name = ") | Should -Be $true -Because 'Test cases should contain a test name in the format `metadata name = ''This is one hell of a test name''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' } It "[] Bicep test deployment files should contain a test description" -TestCases $deploymentTestFileTestCases { @@ -1162,8 +1158,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { param( [object[]] $testFileContent ) - Write-Error 'Not implemented' - + (($testFileContent | Out-String) -match "metadata description = ") | Should -Be $true -Because 'Test cases should contain a test description in the format `metadata description = ''This is one hell of a description''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' } It "[] Bicep test deployment files should contain namePrefix parameter with value ['#_namePrefix_#']" -TestCases $deploymentTestFileTestCases { From 3a6f0a2b56d426ce7e54bfc5145f45cf28dbd440 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 16:27:54 +0100 Subject: [PATCH 07/52] Update to latest --- .../staticValidation/compliance/module.tests.ps1 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 98caa78e5d..013972eabb 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -1150,7 +1150,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { param( [object[]] $testFileContent ) - (($testFileContent | Out-String) -match "metadata name = ") | Should -Be $true -Because 'Test cases should contain a test name in the format `metadata name = ''This is one hell of a test name''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' + (($testFileContent | Out-String) -match "metadata name = .+") | Should -Be $true -Because 'Test cases should contain a test name in the format `metadata name = ''This is one hell of a test name''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' } It "[] Bicep test deployment files should contain a test description" -TestCases $deploymentTestFileTestCases { @@ -1158,7 +1158,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { param( [object[]] $testFileContent ) - (($testFileContent | Out-String) -match "metadata description = ") | Should -Be $true -Because 'Test cases should contain a test description in the format `metadata description = ''This is one hell of a description''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' + (($testFileContent | Out-String) -match "metadata description = .+") | Should -Be $true -Because 'Test cases should contain a test description in the format `metadata description = ''This is one hell of a description''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' } It "[] Bicep test deployment files should contain namePrefix parameter with value ['#_namePrefix_#']" -TestCases $deploymentTestFileTestCases { @@ -1166,7 +1166,9 @@ Describe 'Test file tests' -Tag 'TestTemplate' { param( [object[]] $testFileContent ) - Write-Error 'Not implemented' + + (($testFileContent | Out-String) -match "@description('Optional\. A token to inject into the name of each resource\. This value can be automatically injected by the CI\.')") | Should -Be $true -Because 'The parameter `namePrefix` should have a meaningful description.' + (($testFileContent | Out-String) -match "param namePrefix string = '#_namePrefix_#'") | Should -Be $true -Because 'The test CI needs this value to ensure that deployed resources have unique names.' } It "[] Bicep test deployment files should invoke test like [`module testDeployment '../.*main.bicep' = {`]" -TestCases $deploymentTestFileTestCases { From 4ab6a5bb23b592796960daf61cb831fcf91cd3ac Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 16:38:29 +0100 Subject: [PATCH 08/52] Added module name + small fix --- .../compliance/module.tests.ps1 | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 013972eabb..d5dd1215c6 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -1090,6 +1090,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { $resourceTypeIdentifier = ($moduleFolderPath -split '[\/|\\]{1}avm[\/|\\]{1}(res|ptn)[\/|\\]{1}')[2] -replace '\\', '/' # avm/res// $deploymentTestFileTestCases += @{ + testName = Split-Path (Split-Path $testFilePath) -Leaf testFilePath = $testFilePath testFileContent = $testFileContent moduleFolderName = $resourceTypeIdentifier @@ -1098,7 +1099,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { } } - It "[] Bicep test deployment files should contain serviceShort parameter" -TestCases $deploymentTestFileTestCases { + It "[] [] Bicep test deployment files should contain serviceShort parameter" -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent @@ -1106,7 +1107,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { ($testFileContent -match "^param serviceShort string = '(.*)$") | Should -Not -BeNullOrEmpty -Because 'the module test deployment file should contain a service short parameter using the syntax [param serviceShort string = ''*''].' } - It "[] Bicep test deployment files in a [default] folder should contain a service short with ending [min]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]defaults[\\|\/].*' }) { + It "[] [] Bicep test deployment files in a [default] folder should contain a service short with ending [min]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]defaults[\\|\/].*' }) { param( [object[]] $testFileContent @@ -1119,7 +1120,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { } } - It "[] Bicep test deployment files in a [max] folder should contain a service short with ending [max]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]max[\\|\/].*' }) { + It "[] [] Bicep test deployment files in a [max] folder should contain a service short with ending [max]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]max[\\|\/].*' }) { param( [object[]] $testFileContent @@ -1132,7 +1133,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { } } - It "[] Bicep test deployment files in a [waf-aligned] folder should contain a service short with ending [waf]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]waf\-aligned[\\|\/].*' }) { + It "[] [] Bicep test deployment files in a [waf-aligned] folder should contain a service short with ending [waf]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]waf\-aligned[\\|\/].*' }) { param( [object[]] $testFileContent @@ -1145,7 +1146,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { } } - It "[] Bicep test deployment files should contain a test name" -TestCases $deploymentTestFileTestCases { + It "[] [] Bicep test deployment files should contain a test name" -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent @@ -1153,7 +1154,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { (($testFileContent | Out-String) -match "metadata name = .+") | Should -Be $true -Because 'Test cases should contain a test name in the format `metadata name = ''This is one hell of a test name''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' } - It "[] Bicep test deployment files should contain a test description" -TestCases $deploymentTestFileTestCases { + It "[] [] Bicep test deployment files should contain a test description" -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent @@ -1161,17 +1162,17 @@ Describe 'Test file tests' -Tag 'TestTemplate' { (($testFileContent | Out-String) -match "metadata description = .+") | Should -Be $true -Because 'Test cases should contain a test description in the format `metadata description = ''This is one hell of a description''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' } - It "[] Bicep test deployment files should contain namePrefix parameter with value ['#_namePrefix_#']" -TestCases $deploymentTestFileTestCases { + It "[] [] Bicep test deployment files should contain namePrefix parameter with value ['#_namePrefix_#']" -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent ) - (($testFileContent | Out-String) -match "@description('Optional\. A token to inject into the name of each resource\. This value can be automatically injected by the CI\.')") | Should -Be $true -Because 'The parameter `namePrefix` should have a meaningful description.' + (($testFileContent | Out-String) -match "@description\('Optional\. A token to inject into the name of each resource\. This value can be automatically injected by the CI\.'\)") | Should -Be $true -Because 'The parameter `namePrefix` should have a meaningful description.' (($testFileContent | Out-String) -match "param namePrefix string = '#_namePrefix_#'") | Should -Be $true -Because 'The test CI needs this value to ensure that deployed resources have unique names.' } - It "[] Bicep test deployment files should invoke test like [`module testDeployment '../.*main.bicep' = {`]" -TestCases $deploymentTestFileTestCases { + It "[] [] Bicep test deployment files should invoke test like [`module testDeployment '../.*main.bicep' = {`]" -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent @@ -1182,7 +1183,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { $testIndex -ne -1 | Should -Be $true -Because 'the module test invocation should be in the expected format to allow identification.' } - It '[] Bicep test deployment name should contain [`-test-`].' -TestCases $deploymentTestFileTestCases { + It '[] [] Bicep test deployment name should contain [`-test-`].' -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent @@ -1193,7 +1194,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { $expectedNameFormat | Should -Be $true -Because 'the handle ''-test-'' should be part of the module test invocation''s resource name to allow identification.' } - It '[] Bicep test deployment should have parameter [`serviceShort`].' -TestCases $deploymentTestFileTestCases { + It '[] [] Bicep test deployment should have parameter [`serviceShort`].' -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent From 9bb64bde34d8b5de3d1b2bda2a0fe2687855b35f Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 17:31:08 +0100 Subject: [PATCH 09/52] Fixed kvlt --- avm/res/key-vault/vault/access-policy/main.json | 4 ++-- avm/res/key-vault/vault/key/main.json | 4 ++-- avm/res/key-vault/vault/main.bicep | 3 +++ avm/res/key-vault/vault/main.json | 12 +++++++++++- avm/res/key-vault/vault/secret/main.json | 4 ++-- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/avm/res/key-vault/vault/access-policy/main.json b/avm/res/key-vault/vault/access-policy/main.json index 9b6725ecc4..8aa7ea483d 100644 --- a/avm/res/key-vault/vault/access-policy/main.json +++ b/avm/res/key-vault/vault/access-policy/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "9999250509448584761" + "version": "0.23.1.45101", + "templateHash": "4111939022872407830" }, "name": "Key Vault Access Policies", "description": "This module deploys a Key Vault Access Policy.", diff --git a/avm/res/key-vault/vault/key/main.json b/avm/res/key-vault/vault/key/main.json index 6ecce215ac..6e85c7d6ad 100644 --- a/avm/res/key-vault/vault/key/main.json +++ b/avm/res/key-vault/vault/key/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "15591839680984542683" + "version": "0.23.1.45101", + "templateHash": "2691621623448325959" }, "name": "Key Vault Keys", "description": "This module deploys a Key Vault Key.", diff --git a/avm/res/key-vault/vault/main.bicep b/avm/res/key-vault/vault/main.bicep index 4e62950d9c..ae038cf1f5 100644 --- a/avm/res/key-vault/vault/main.bicep +++ b/avm/res/key-vault/vault/main.bicep @@ -353,6 +353,9 @@ type roleAssignmentType = { @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container"') condition: string? + @description('Optional. Version of the condition.') + conditionVersion: '2.0'? + @description('Optional. The Resource Id of the delegated managed identity resource.') delegatedManagedIdentityResourceId: string? }[]? diff --git a/avm/res/key-vault/vault/main.json b/avm/res/key-vault/vault/main.json index bfcfb41b93..8478ccde4e 100644 --- a/avm/res/key-vault/vault/main.json +++ b/avm/res/key-vault/vault/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "8353941507512521049" + "templateHash": "1913015049301539374" }, "name": "Key Vaults", "description": "This module deploys a Key Vault.", @@ -164,6 +164,16 @@ "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" } }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, "delegatedManagedIdentityResourceId": { "type": "string", "nullable": true, diff --git a/avm/res/key-vault/vault/secret/main.json b/avm/res/key-vault/vault/secret/main.json index 62c5c52a19..f778252db1 100644 --- a/avm/res/key-vault/vault/secret/main.json +++ b/avm/res/key-vault/vault/secret/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "11139788551431901948" + "version": "0.23.1.45101", + "templateHash": "9180551172362989336" }, "name": "Key Vault Secrets", "description": "This module deploys a Key Vault Secret.", From 68e2bd2fbc6301b199fd0258411da31781ba4380 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 17:56:38 +0100 Subject: [PATCH 10/52] Small caching fix --- .../pipelines/staticValidation/compliance/module.tests.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index d5dd1215c6..8dc880fdb9 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -930,10 +930,12 @@ Describe 'Module tests' -Tag 'Module' { throw ($templateNotFoundException -f $moduleFolderPath) } $convertedTemplates[$moduleFolderPathKey] = @{ - templateContent = $templateContent + templateContent = $templateContent + templateFilePath = $templateFilePath } } else { $templateContent = $convertedTemplates[$moduleFolderPathKey].templateContent + $templateFilePath = $convertedTemplates[$moduleFolderPathKey].templateFilePath } $udtSpecificTestCases += @{ From 1a013c2a4115610d4260515205158ed831860de8 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 19:25:21 +0100 Subject: [PATCH 11/52] Small fix and enabled passthru of warnings to GH --- .../compliance/Set-PesterGitHubOutput.ps1 | 72 ++++++++++++++++--- .../compliance/module.tests.ps1 | 9 ++- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 index 4c84e61eaf..ada2dc98e9 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 @@ -81,10 +81,12 @@ function Set-PesterGitHubOutput { $passedTests = $PesterTestResults.Passed $failedTests = $PesterTestResults.Failed $skippedTests = $PesterTestResults.Skipped + $testsWithWarnings = ($passedTests + $failedTests + $skippedTests) | Where-Object { $_.StandardOutput.Keys -eq 'Warning' } Write-Verbose ('Formatting [{0}] passed tests' -f $passedTests.Count) Write-Verbose ('Formatting [{0}] failed tests' -f $failedTests.Count) Write-Verbose ('Formatting [{0}] skipped tests' -f $skippedTests.Count) + Write-Verbose ('Formatting [{0}] tests with explicit warnings' -f $warnings.Count) ###################### # Set output content # @@ -98,9 +100,9 @@ function Set-PesterGitHubOutput { ## Header table $fileContent += [System.Collections.ArrayList]@( - '| Total No. of Processed Tests| Passed Tests :white_check_mark: | Failed Tests :x: | Skipped Tests :paperclip: |', - '| :-- | :-- | :-- | :-- |' - ('| {0} | {1} | {2} | {3} |' -f $PesterTestResults.TotalCount, $passedTests.count , $failedTests.count, $skippedTests.count), + '| Total No. of Processed Tests| Passed Tests :white_check_mark: | Failed Tests :x: | Skipped Tests :paperclip: | Tests with warnings :warning: |', + '| :-- | :-- | :-- | :-- |', + ('| {0} | {1} | {2} | {3} |' -f $PesterTestResults.TotalCount, $passedTests.count , $failedTests.count, $skippedTests.count, $testsWithWarnings.count), '' ) @@ -140,8 +142,7 @@ function Set-PesterGitHubOutput { $fileContent += '| {0} | {1} | {2} |' -f $testName, $errorMessage, $testReference } - } - else { + } else { $fileContent += ('No tests failed.') } @@ -164,6 +165,8 @@ function Set-PesterGitHubOutput { if (($passedTests.Count -gt 0)) { + # TODO: Add support for outputs + $fileContent += [System.Collections.ArrayList]@( '| Name | Source |', '| :-- | :-- |' @@ -185,8 +188,7 @@ function Set-PesterGitHubOutput { $fileContent += '| {0} | {1} |' -f $testName, $testReference } - } - else { + } else { $fileContent += ('No tests passed.') } @@ -222,8 +224,8 @@ function Set-PesterGitHubOutput { $reason = ('Test {0}' -f $skippedTest.ErrorRecord.Exception.Message -replace '\|', '\|').Trim() - $testLine = $passedTest.ScriptBlock.StartPosition.StartLine - $testFile = (($passedTest.ScriptBlock.File -split '[\/|\\](avm[\/|\\])')[-2, -1] -join '') -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1] + $testLine = $skippedTest.ScriptBlock.StartPosition.StartLine + $testFile = (($skippedTest.ScriptBlock.File -split '[\/|\\](avm[\/|\\])')[-2, -1] -join '') -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1] $testReference = '{0}:{1}' -f (Split-Path $testFile -Leaf), $testLine if (-not [String]::IsNullOrEmpty($GitHubRepository) -and -not [String]::IsNullOrEmpty($BranchName)) { @@ -233,8 +235,7 @@ function Set-PesterGitHubOutput { $fileContent += '| {0} | {1} | {2} |' -f $testName, $reason, $testReference } - } - else { + } else { $fileContent += ('No tests were skipped.') } @@ -244,6 +245,55 @@ function Set-PesterGitHubOutput { '' ) + ################## + ## Warnings ## + ################## + + Write-Verbose 'Adding warnings' + $fileContent += [System.Collections.ArrayList]@( + '', + '
', + 'List of explicit warnings', + '' + ) + + if ($testsWithWarnings.Count -gt 0) { + + $fileContent += [System.Collections.ArrayList]@( + '| Name | Warning | Source |', + '| :-- | :-- | :-- |' + ) + foreach ($test in ($testsWithWarnings | Sort-Object -Property { $PSItem.ExpandedName }) ) { + foreach ($warning in $test.StandardOutput.Warning) { + $intermediateNameElements = $test.Path + $intermediateNameElements[-1] = '**{0}**' -f $test.ExpandedName + $testName = (($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|').Trim() + + $testLine = $test.ScriptBlock.StartPosition.StartLine + $testFile = (($test.ScriptBlock.File -split '[\/|\\](avm[\/|\\])')[-2, -1] -join '') -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1] + + $testReference = '{0}:{1}' -f (Split-Path $testFile -Leaf), $testLine + if (-not [String]::IsNullOrEmpty($GitHubRepository) -and -not [String]::IsNullOrEmpty($BranchName)) { + # Creating URL to test file to enable users to 'click' on it + $testReference = "[$testReference](https://github.com/$GitHubRepository/blob/$BranchName/$testFile#L$testLine)" + } + + $fileContent += '| {0} | {1} | {2} |' -f $testName, ($warning -replace '\|', '\|'), $testReference + } + } + } else { + $fileContent += ('No tests with warnings.') + } + + $fileContent += [System.Collections.ArrayList]@( + '', + '
', + '' + ) + + + + if ($PSCmdlet.ShouldProcess("Test results file in path [$OutputFilePath]", 'Create')) { $null = New-Item -Path $OutputFilePath -Force -Value ($fileContent | Out-String) } diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 8dc880fdb9..8ba6483758 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -990,6 +990,7 @@ Describe 'Module tests' -Tag 'Module' { parameterName = $udtCase.parameterName udtName = $udtCase.udtName expectedUdtUrl = $udtCase.udtExpectedUrl ? $udtCase.udtExpectedUrl : '' + link = $udtCase.link } } } @@ -1042,7 +1043,13 @@ Describe 'Module tests' -Tag 'Module' { } if ($formattedDiff.Count -gt 0) { - Write-Warning ("The implemented user-defined type is not the same as the expected [user-defined type]({0}) defined in the [AVM specs]({1}) and should not have diff`n{2}" -f $expectedUdtUrl, $link, ($formattedDiff | Out-String)) + $warningMessage = "The implemented user-defined type is not the same as the expected [user-defined type]({0}) defined in the [AVM specs]({1}) and should not have diff`n{2}" -f $expectedUdtUrl, $link, ($formattedDiff | Out-String) + Write-Warning $warningMessage + + # Adding also to output to show in GitHub CI + Write-Output @{ + Warning = $warningMessage + } } } } else { From 1c2fc8ab54eafaef98ab28b8feaa3073d9469436 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 19:31:09 +0100 Subject: [PATCH 12/52] More updates --- .../staticValidation/compliance/Set-PesterGitHubOutput.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 index ada2dc98e9..e716f14f5b 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 @@ -101,8 +101,8 @@ function Set-PesterGitHubOutput { ## Header table $fileContent += [System.Collections.ArrayList]@( '| Total No. of Processed Tests| Passed Tests :white_check_mark: | Failed Tests :x: | Skipped Tests :paperclip: | Tests with warnings :warning: |', - '| :-- | :-- | :-- | :-- |', - ('| {0} | {1} | {2} | {3} |' -f $PesterTestResults.TotalCount, $passedTests.count , $failedTests.count, $skippedTests.count, $testsWithWarnings.count), + '| :-- | :-- | :-- | :-- | :-- |', + ('| {0} | {1} | {2} | {3} | {4} |' -f $PesterTestResults.TotalCount, $passedTests.count , $failedTests.count, $skippedTests.count, $testsWithWarnings.count), '' ) @@ -278,7 +278,7 @@ function Set-PesterGitHubOutput { $testReference = "[$testReference](https://github.com/$GitHubRepository/blob/$BranchName/$testFile#L$testLine)" } - $fileContent += '| {0} | {1} | {2} |' -f $testName, ($warning -replace '\|', '\|'), $testReference + $fileContent += '| {0} | {1} | {2} |' -f $testName, (($warning -join '
') -replace '\|', '\|'), $testReference } } } else { From d9c6dd5deffd8fd307107e5ce8be98961163996a Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 20:16:57 +0100 Subject: [PATCH 13/52] Update to latest --- .../staticValidation/compliance/Set-PesterGitHubOutput.ps1 | 4 +--- .../pipelines/staticValidation/compliance/module.tests.ps1 | 6 ++++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 index e716f14f5b..e1c207936d 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 @@ -165,8 +165,6 @@ function Set-PesterGitHubOutput { if (($passedTests.Count -gt 0)) { - # TODO: Add support for outputs - $fileContent += [System.Collections.ArrayList]@( '| Name | Source |', '| :-- | :-- |' @@ -278,7 +276,7 @@ function Set-PesterGitHubOutput { $testReference = "[$testReference](https://github.com/$GitHubRepository/blob/$BranchName/$testFile#L$testLine)" } - $fileContent += '| {0} | {1} | {2} |' -f $testName, (($warning -join '
') -replace '\|', '\|'), $testReference + $fileContent += ('| {0} | {1} | {2} |' -f $testName, $warning, $testReference) } } } else { diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 8ba6483758..997ac427a6 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -1043,12 +1043,14 @@ Describe 'Module tests' -Tag 'Module' { } if ($formattedDiff.Count -gt 0) { - $warningMessage = "The implemented user-defined type is not the same as the expected [user-defined type]({0}) defined in the [AVM specs]({1}) and should not have diff`n{2}" -f $expectedUdtUrl, $link, ($formattedDiff | Out-String) + $warningMessage = "The implemented user-defined type is not the same as the expected user-defined type ({0}) defined in the AVM specs ({1}) and should not have diff`n{2}" -f $expectedUdtUrl, $link, ($formattedDiff | Out-String) Write-Warning $warningMessage # Adding also to output to show in GitHub CI + $mdFormattedDiff = ($formattedDiff -join '
') -replace '\|', '\|' + $mdFormattedWarningMessage = "The implemented user-defined type is not the same as the expected [user-defined type]({0}) defined in the [AVM specs]({1}) and should not have diff
{2}
" -f $expectedUdtUrl, $link, $mdFormattedDiff Write-Output @{ - Warning = $warningMessage + Warning = $mdFormattedWarningMessage } } } From dd0c343fb884869740436c238b367d13029fc549 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 21:00:06 +0100 Subject: [PATCH 14/52] Updated test names --- .../compliance/module.tests.ps1 | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 997ac427a6..e46c6fc17d 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -996,7 +996,7 @@ Describe 'Module tests' -Tag 'Module' { } - It "[] If template has [] parameter, it should implement the user-defined type []" -TestCases $udtTestCases { + It "[] If template has a parameter [], it should implement the user-defined type []" -TestCases $udtTestCases { param( [hashtable] $templateFileContent, @@ -1059,7 +1059,7 @@ Describe 'Module tests' -Tag 'Module' { } } - It "[] If a [managedIdentitiesType] UDT definition exists and supports system-assigned-identities, the template should have an output for its principal ID." -TestCases $udtSpecificTestCases { + It "[] If a UDT definition [managedIdentitiesType] exists and supports system-assigned-identities, the template should have an output for its principal ID." -TestCases $udtSpecificTestCases { param( [hashtable] $templateFileContent @@ -1072,7 +1072,7 @@ Describe 'Module tests' -Tag 'Module' { } } - It "[] If a [tags] parameter exists it should be nullable." -TestCases $udtSpecificTestCases { + It "[] If a parameter [tags] exists it should be nullable." -TestCases $udtSpecificTestCases { param( [hashtable] $templateFileContent @@ -1110,15 +1110,15 @@ Describe 'Test file tests' -Tag 'TestTemplate' { } } - It "[] [] Bicep test deployment files should contain serviceShort parameter" -TestCases $deploymentTestFileTestCases { + It "[] [] Bicep test deployment files should contain a parameter [serviceShort]" -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent ) - ($testFileContent -match "^param serviceShort string = '(.*)$") | Should -Not -BeNullOrEmpty -Because 'the module test deployment file should contain a service short parameter using the syntax [param serviceShort string = ''*''].' + ($testFileContent -match "^param serviceShort string = '(.*)$") | Should -Not -BeNullOrEmpty -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*''].' } - It "[] [] Bicep test deployment files in a [default] folder should contain a service short with ending [min]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]defaults[\\|\/].*' }) { + It "[] [] Bicep test deployment files in a [waf-aligned] folder should have a parameter [serviceShort] with a value ending with [min]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]defaults[\\|\/].*' }) { param( [object[]] $testFileContent @@ -1127,11 +1127,11 @@ Describe 'Test file tests' -Tag 'TestTemplate' { if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { $Matches[1] | Should -BeLike "*min" } else { - Set-ItResult -Skipped -Because 'the module test deployment file should contain a service short parameter using the syntax [param serviceShort string = ''*min''] but it doesn''t.' + Set-ItResult -Skipped -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*min''] but it doesn''t.' } } - It "[] [] Bicep test deployment files in a [max] folder should contain a service short with ending [max]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]max[\\|\/].*' }) { + It "[] [] Bicep test deployment files in a [waf-aligned] folder should have a [serviceShort] parameter with a value ending with [max]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]max[\\|\/].*' }) { param( [object[]] $testFileContent @@ -1140,11 +1140,11 @@ Describe 'Test file tests' -Tag 'TestTemplate' { if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { $Matches[1] | Should -BeLike "*max" } else { - Set-ItResult -Skipped -Because 'the module test deployment file should contain a service short parameter using the syntax [param serviceShort string = ''*max''] but it doesn''t.' + Set-ItResult -Skipped -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*max''] but it doesn''t.' } } - It "[] [] Bicep test deployment files in a [waf-aligned] folder should contain a service short with ending [waf]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]waf\-aligned[\\|\/].*' }) { + It "[] [] Bicep test deployment files in a [waf-aligned] folder should have a [serviceShort] parameter with a value ending with [waf]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]waf\-aligned[\\|\/].*' }) { param( [object[]] $testFileContent @@ -1153,34 +1153,34 @@ Describe 'Test file tests' -Tag 'TestTemplate' { if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { $Matches[1] | Should -BeLike "*waf" } else { - Set-ItResult -Skipped -Because 'the module test deployment file should contain a service short parameter using the syntax [param serviceShort string = ''*waf''] but it doesn''t.' + Set-ItResult -Skipped -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*waf''] but it doesn''t.' } } - It "[] [] Bicep test deployment files should contain a test name" -TestCases $deploymentTestFileTestCases { + It "[] [] Bicep test deployment files should contain a metadata string [name]" -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent ) - (($testFileContent | Out-String) -match "metadata name = .+") | Should -Be $true -Because 'Test cases should contain a test name in the format `metadata name = ''This is one hell of a test name''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' + (($testFileContent | Out-String) -match "metadata name = .+") | Should -Be $true -Because 'Test cases should contain a metadata string [name] in the format `metadata name = ''This is one hell of a test name''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' } - It "[] [] Bicep test deployment files should contain a test description" -TestCases $deploymentTestFileTestCases { + It "[] [] Bicep test deployment files should contain a metadata string [description]" -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent ) - (($testFileContent | Out-String) -match "metadata description = .+") | Should -Be $true -Because 'Test cases should contain a test description in the format `metadata description = ''This is one hell of a description''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' + (($testFileContent | Out-String) -match "metadata description = .+") | Should -Be $true -Because 'Test cases should contain a metadata string [description] in the format `metadata description = ''This is one hell of a description''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' } - It "[] [] Bicep test deployment files should contain namePrefix parameter with value ['#_namePrefix_#']" -TestCases $deploymentTestFileTestCases { + It "[] [] Bicep test deployment files should contain a parameter [namePrefix] with value ['#_namePrefix_#']" -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent ) - (($testFileContent | Out-String) -match "@description\('Optional\. A token to inject into the name of each resource\. This value can be automatically injected by the CI\.'\)") | Should -Be $true -Because 'The parameter `namePrefix` should have a meaningful description.' - (($testFileContent | Out-String) -match "param namePrefix string = '#_namePrefix_#'") | Should -Be $true -Because 'The test CI needs this value to ensure that deployed resources have unique names.' + (($testFileContent | Out-String) -match "@description\('Optional\. A token to inject into the name of each resource\. This value can be automatically injected by the CI\.'\)") | Should -Be $true -Because 'The parameter [namePrefix] should have the expected description.' + (($testFileContent | Out-String) -match "param namePrefix string = '#_namePrefix_#'") | Should -Be $true -Because 'The test CI needs this value to ensure that deployed resources have unique names per fork.' } It "[] [] Bicep test deployment files should invoke test like [`module testDeployment '../.*main.bicep' = {`]" -TestCases $deploymentTestFileTestCases { From 2ebd45891d75ce145710733437cb82c5814128c4 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 23:32:08 +0100 Subject: [PATCH 15/52] JSON rollback --- avm/res/key-vault/vault/access-policy/main.json | 4 ++-- avm/res/key-vault/vault/key/main.json | 4 ++-- avm/res/key-vault/vault/main.json | 16 ++++++++-------- avm/res/key-vault/vault/secret/main.json | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/avm/res/key-vault/vault/access-policy/main.json b/avm/res/key-vault/vault/access-policy/main.json index 8aa7ea483d..9b6725ecc4 100644 --- a/avm/res/key-vault/vault/access-policy/main.json +++ b/avm/res/key-vault/vault/access-policy/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "4111939022872407830" + "version": "0.22.6.54827", + "templateHash": "9999250509448584761" }, "name": "Key Vault Access Policies", "description": "This module deploys a Key Vault Access Policy.", diff --git a/avm/res/key-vault/vault/key/main.json b/avm/res/key-vault/vault/key/main.json index 6e85c7d6ad..6ecce215ac 100644 --- a/avm/res/key-vault/vault/key/main.json +++ b/avm/res/key-vault/vault/key/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "2691621623448325959" + "version": "0.22.6.54827", + "templateHash": "15591839680984542683" }, "name": "Key Vault Keys", "description": "This module deploys a Key Vault Key.", diff --git a/avm/res/key-vault/vault/main.json b/avm/res/key-vault/vault/main.json index 8478ccde4e..f10c40c0fb 100644 --- a/avm/res/key-vault/vault/main.json +++ b/avm/res/key-vault/vault/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "1913015049301539374" + "version": "0.22.6.54827", + "templateHash": "9188769706526490100" }, "name": "Key Vaults", "description": "This module deploys a Key Vault.", @@ -682,8 +682,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "4111939022872407830" + "version": "0.22.6.54827", + "templateHash": "9999250509448584761" }, "name": "Key Vault Access Policies", "description": "This module deploys a Key Vault Access Policy.", @@ -815,8 +815,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9180551172362989336" + "version": "0.22.6.54827", + "templateHash": "11139788551431901948" }, "name": "Key Vault Secrets", "description": "This module deploys a Key Vault Secret.", @@ -1104,8 +1104,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "2691621623448325959" + "version": "0.22.6.54827", + "templateHash": "15591839680984542683" }, "name": "Key Vault Keys", "description": "This module deploys a Key Vault Key.", diff --git a/avm/res/key-vault/vault/secret/main.json b/avm/res/key-vault/vault/secret/main.json index f778252db1..62c5c52a19 100644 --- a/avm/res/key-vault/vault/secret/main.json +++ b/avm/res/key-vault/vault/secret/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9180551172362989336" + "version": "0.22.6.54827", + "templateHash": "11139788551431901948" }, "name": "Key Vault Secrets", "description": "This module deploys a Key Vault Secret.", From f6caf7e44eadf5ed72103aa3bcada9c3cf1c8fce Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 23:49:57 +0100 Subject: [PATCH 16/52] Updated regex --- .../compliance/Set-PesterGitHubOutput.ps1 | 2 +- .../staticValidation/compliance/module.tests.ps1 | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 index e1c207936d..a8a773640e 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 @@ -131,7 +131,7 @@ function Set-PesterGitHubOutput { $errorTestLine = $failedTest.ErrorRecord.TargetObject.Line $errorTestFile = (($failedTest.ErrorRecord.TargetObject.File -split '[\/|\\](avm[\/|\\])')[-2, -1] -join '') -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1] - $errorMessage = $failedTest.ErrorRecord.TargetObject.Message.Trim() -replace '\n', '
' # Replace new lines with
to enable line breaks in markdown + $errorMessage = ($failedTest.ErrorRecord.TargetObject.Message.Trim() -replace '_', '\_') -replace '\n', '
' # Replace new lines with
to enable line breaks in markdown $testReference = '{0}:{1}' -f (Split-Path $errorTestFile -Leaf), $errorTestLine diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index e46c6fc17d..6b7c50807b 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -1162,7 +1162,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { param( [object[]] $testFileContent ) - (($testFileContent | Out-String) -match "metadata name = .+") | Should -Be $true -Because 'Test cases should contain a metadata string [name] in the format `metadata name = ''This is one hell of a test name''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' + ($testFileContent | Out-String) | Should -Match "metadata name = .+" -Because 'Test cases should contain a metadata string [name] in the format `metadata name = ''This is one hell of a test name''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' } It "[] [] Bicep test deployment files should contain a metadata string [description]" -TestCases $deploymentTestFileTestCases { @@ -1170,7 +1170,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { param( [object[]] $testFileContent ) - (($testFileContent | Out-String) -match "metadata description = .+") | Should -Be $true -Because 'Test cases should contain a metadata string [description] in the format `metadata description = ''This is one hell of a description''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' + ($testFileContent | Out-String) | Should -Match "metadata description = .+" -Because 'Test cases should contain a metadata string [description] in the format `metadata description = ''This is one hell of a description''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' } It "[] [] Bicep test deployment files should contain a parameter [namePrefix] with value ['#_namePrefix_#']" -TestCases $deploymentTestFileTestCases { @@ -1179,8 +1179,8 @@ Describe 'Test file tests' -Tag 'TestTemplate' { [object[]] $testFileContent ) - (($testFileContent | Out-String) -match "@description\('Optional\. A token to inject into the name of each resource\. This value can be automatically injected by the CI\.'\)") | Should -Be $true -Because 'The parameter [namePrefix] should have the expected description.' - (($testFileContent | Out-String) -match "param namePrefix string = '#_namePrefix_#'") | Should -Be $true -Because 'The test CI needs this value to ensure that deployed resources have unique names per fork.' + ($testFileContent | Out-String) | Should -Match "@description\('Optional\. A token to inject into the name of each resource\. This value can be automatically injected by the CI\.'\)" -Because 'The parameter [namePrefix] should have the expected description.' + ($testFileContent | Out-String) | Should -Match "param namePrefix string = '#_namePrefix_#'" -Because 'The test CI needs this value to ensure that deployed resources have unique names per fork.' } It "[] [] Bicep test deployment files should invoke test like [`module testDeployment '../.*main.bicep' = {`]" -TestCases $deploymentTestFileTestCases { From f56f66af2a884495d5eeafb4f580d76960ee93f3 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 23:52:45 +0100 Subject: [PATCH 17/52] Removed assertion --- .../pipelines/staticValidation/compliance/module.tests.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 6b7c50807b..b7c9ab905f 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -1179,7 +1179,6 @@ Describe 'Test file tests' -Tag 'TestTemplate' { [object[]] $testFileContent ) - ($testFileContent | Out-String) | Should -Match "@description\('Optional\. A token to inject into the name of each resource\. This value can be automatically injected by the CI\.'\)" -Because 'The parameter [namePrefix] should have the expected description.' ($testFileContent | Out-String) | Should -Match "param namePrefix string = '#_namePrefix_#'" -Because 'The test CI needs this value to ensure that deployed resources have unique names per fork.' } From 282b640a884885ba59db841457ddfdc5ea1ec59e Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Wed, 8 Nov 2023 23:58:17 +0100 Subject: [PATCH 18/52] Update to latest --- .../compliance/Set-PesterGitHubOutput.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 index a8a773640e..d23f8d4f8f 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 @@ -127,7 +127,7 @@ function Set-PesterGitHubOutput { $intermediateNameElements = $failedTest.Path $intermediateNameElements[-1] = '**{0}**' -f $failedTest.ExpandedName - $testName = (($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|').Trim() + $testName = ((($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|') -replace '_', '\_').Trim() $errorTestLine = $failedTest.ErrorRecord.TargetObject.Line $errorTestFile = (($failedTest.ErrorRecord.TargetObject.File -split '[\/|\\](avm[\/|\\])')[-2, -1] -join '') -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1] @@ -173,7 +173,7 @@ function Set-PesterGitHubOutput { $intermediateNameElements = $passedTest.Path $intermediateNameElements[-1] = '**{0}**' -f $passedTest.ExpandedName - $testName = (($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|').Trim() + $testName = ((($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|') -replace '_', '\_').Trim() $testLine = $passedTest.ScriptBlock.StartPosition.StartLine $testFile = (($passedTest.ScriptBlock.File -split '[\/|\\](avm[\/|\\])')[-2, -1] -join '') -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1] @@ -218,7 +218,7 @@ function Set-PesterGitHubOutput { $intermediateNameElements = $skippedTest.Path $intermediateNameElements[-1] = '**{0}**' -f $skippedTest.ExpandedName - $testName = (($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|').Trim() + $testName = ((($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|') -replace '_', '\_').Trim() $reason = ('Test {0}' -f $skippedTest.ErrorRecord.Exception.Message -replace '\|', '\|').Trim() @@ -265,7 +265,7 @@ function Set-PesterGitHubOutput { foreach ($warning in $test.StandardOutput.Warning) { $intermediateNameElements = $test.Path $intermediateNameElements[-1] = '**{0}**' -f $test.ExpandedName - $testName = (($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|').Trim() + $testName = ((($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|') -replace '_', '\_').Trim() $testLine = $test.ScriptBlock.StartPosition.StartLine $testFile = (($test.ScriptBlock.File -split '[\/|\\](avm[\/|\\])')[-2, -1] -join '') -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1] From c025f526216b35a93c6ffee5dfe4beb3dc29cada Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Thu, 9 Nov 2023 07:32:30 +0100 Subject: [PATCH 19/52] Update avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 Co-authored-by: Erika Gressi <56914614+eriqua@users.noreply.github.com> --- .../pipelines/staticValidation/compliance/module.tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index b7c9ab905f..cdd40eb5ed 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -1131,7 +1131,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { } } - It "[] [] Bicep test deployment files in a [waf-aligned] folder should have a [serviceShort] parameter with a value ending with [max]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]max[\\|\/].*' }) { + It "[] [] Bicep test deployment files in a [max] folder should have a [serviceShort] parameter with a value ending with [max]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]max[\\|\/].*' }) { param( [object[]] $testFileContent From 405901aff9656cb669db03eb90cfb96f2fa13908 Mon Sep 17 00:00:00 2001 From: Alexander Sehr Date: Thu, 9 Nov 2023 07:33:08 +0100 Subject: [PATCH 20/52] Update avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 Co-authored-by: Erika Gressi <56914614+eriqua@users.noreply.github.com> --- .../pipelines/staticValidation/compliance/module.tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index cdd40eb5ed..a2ac22d565 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -1118,7 +1118,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { ($testFileContent -match "^param serviceShort string = '(.*)$") | Should -Not -BeNullOrEmpty -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*''].' } - It "[] [] Bicep test deployment files in a [waf-aligned] folder should have a parameter [serviceShort] with a value ending with [min]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]defaults[\\|\/].*' }) { + It "[] [] Bicep test deployment files in a [defaults] folder should have a parameter [serviceShort] with a value ending with [min]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]defaults[\\|\/].*' }) { param( [object[]] $testFileContent From ef24d1f1e65cad599a9f8eaf311a4aa41f1452db Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Thu, 9 Nov 2023 19:29:56 +0100 Subject: [PATCH 21/52] Rollback of unrelated changes --- .../compliance/Set-PesterGitHubOutput.ps1 | 71 +---- .../compliance/module.tests.ps1 | 291 +++--------------- 2 files changed, 45 insertions(+), 317 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 index d23f8d4f8f..66561b92fe 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 @@ -81,12 +81,10 @@ function Set-PesterGitHubOutput { $passedTests = $PesterTestResults.Passed $failedTests = $PesterTestResults.Failed $skippedTests = $PesterTestResults.Skipped - $testsWithWarnings = ($passedTests + $failedTests + $skippedTests) | Where-Object { $_.StandardOutput.Keys -eq 'Warning' } Write-Verbose ('Formatting [{0}] passed tests' -f $passedTests.Count) Write-Verbose ('Formatting [{0}] failed tests' -f $failedTests.Count) Write-Verbose ('Formatting [{0}] skipped tests' -f $skippedTests.Count) - Write-Verbose ('Formatting [{0}] tests with explicit warnings' -f $warnings.Count) ###################### # Set output content # @@ -100,9 +98,9 @@ function Set-PesterGitHubOutput { ## Header table $fileContent += [System.Collections.ArrayList]@( - '| Total No. of Processed Tests| Passed Tests :white_check_mark: | Failed Tests :x: | Skipped Tests :paperclip: | Tests with warnings :warning: |', - '| :-- | :-- | :-- | :-- | :-- |', - ('| {0} | {1} | {2} | {3} | {4} |' -f $PesterTestResults.TotalCount, $passedTests.count , $failedTests.count, $skippedTests.count, $testsWithWarnings.count), + '| Total No. of Processed Tests| Passed Tests :white_check_mark: | Failed Tests :x: | Skipped Tests :paperclip: |', + '| :-- | :-- | :-- | :-- |' + ('| {0} | {1} | {2} | {3} |' -f $PesterTestResults.TotalCount, $passedTests.count , $failedTests.count, $skippedTests.count), '' ) @@ -127,11 +125,11 @@ function Set-PesterGitHubOutput { $intermediateNameElements = $failedTest.Path $intermediateNameElements[-1] = '**{0}**' -f $failedTest.ExpandedName - $testName = ((($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|') -replace '_', '\_').Trim() + $testName = (($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|').Trim() $errorTestLine = $failedTest.ErrorRecord.TargetObject.Line $errorTestFile = (($failedTest.ErrorRecord.TargetObject.File -split '[\/|\\](avm[\/|\\])')[-2, -1] -join '') -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1] - $errorMessage = ($failedTest.ErrorRecord.TargetObject.Message.Trim() -replace '_', '\_') -replace '\n', '
' # Replace new lines with
to enable line breaks in markdown + $errorMessage = $failedTest.ErrorRecord.TargetObject.Message.Trim() -replace '\n', '
' # Replace new lines with
to enable line breaks in markdown $testReference = '{0}:{1}' -f (Split-Path $errorTestFile -Leaf), $errorTestLine @@ -173,7 +171,7 @@ function Set-PesterGitHubOutput { $intermediateNameElements = $passedTest.Path $intermediateNameElements[-1] = '**{0}**' -f $passedTest.ExpandedName - $testName = ((($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|') -replace '_', '\_').Trim() + $testName = (($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|').Trim() $testLine = $passedTest.ScriptBlock.StartPosition.StartLine $testFile = (($passedTest.ScriptBlock.File -split '[\/|\\](avm[\/|\\])')[-2, -1] -join '') -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1] @@ -218,12 +216,12 @@ function Set-PesterGitHubOutput { $intermediateNameElements = $skippedTest.Path $intermediateNameElements[-1] = '**{0}**' -f $skippedTest.ExpandedName - $testName = ((($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|') -replace '_', '\_').Trim() + $testName = (($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|').Trim() $reason = ('Test {0}' -f $skippedTest.ErrorRecord.Exception.Message -replace '\|', '\|').Trim() - $testLine = $skippedTest.ScriptBlock.StartPosition.StartLine - $testFile = (($skippedTest.ScriptBlock.File -split '[\/|\\](avm[\/|\\])')[-2, -1] -join '') -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1] + $testLine = $passedTest.ScriptBlock.StartPosition.StartLine + $testFile = (($passedTest.ScriptBlock.File -split '[\/|\\](avm[\/|\\])')[-2, -1] -join '') -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1] $testReference = '{0}:{1}' -f (Split-Path $testFile -Leaf), $testLine if (-not [String]::IsNullOrEmpty($GitHubRepository) -and -not [String]::IsNullOrEmpty($BranchName)) { @@ -243,57 +241,8 @@ function Set-PesterGitHubOutput { '' ) - ################## - ## Warnings ## - ################## - - Write-Verbose 'Adding warnings' - $fileContent += [System.Collections.ArrayList]@( - '', - '
', - 'List of explicit warnings', - '' - ) - - if ($testsWithWarnings.Count -gt 0) { - - $fileContent += [System.Collections.ArrayList]@( - '| Name | Warning | Source |', - '| :-- | :-- | :-- |' - ) - foreach ($test in ($testsWithWarnings | Sort-Object -Property { $PSItem.ExpandedName }) ) { - foreach ($warning in $test.StandardOutput.Warning) { - $intermediateNameElements = $test.Path - $intermediateNameElements[-1] = '**{0}**' -f $test.ExpandedName - $testName = ((($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|') -replace '_', '\_').Trim() - - $testLine = $test.ScriptBlock.StartPosition.StartLine - $testFile = (($test.ScriptBlock.File -split '[\/|\\](avm[\/|\\])')[-2, -1] -join '') -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1] - - $testReference = '{0}:{1}' -f (Split-Path $testFile -Leaf), $testLine - if (-not [String]::IsNullOrEmpty($GitHubRepository) -and -not [String]::IsNullOrEmpty($BranchName)) { - # Creating URL to test file to enable users to 'click' on it - $testReference = "[$testReference](https://github.com/$GitHubRepository/blob/$BranchName/$testFile#L$testLine)" - } - - $fileContent += ('| {0} | {1} | {2} |' -f $testName, $warning, $testReference) - } - } - } else { - $fileContent += ('No tests with warnings.') - } - - $fileContent += [System.Collections.ArrayList]@( - '', - '
', - '' - ) - - - - if ($PSCmdlet.ShouldProcess("Test results file in path [$OutputFilePath]", 'Create')) { $null = New-Item -Path $OutputFilePath -Force -Value ($fileContent | Out-String) } Write-Verbose "Create results file [$outputFilePath]" -} +} \ No newline at end of file diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index a2ac22d565..d975dea940 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -3,7 +3,7 @@ param ( [Parameter(Mandatory = $false)] [array] $moduleFolderPaths = ((Get-ChildItem $repoRootPath -Recurse -Directory -Force).FullName | Where-Object { - (Get-ChildItem $_ -File -Depth 0 -Include @('main.bicep') -Force).Count -gt 0 + (Get-ChildItem $_ -File -Depth 0 -Include @('main.json', 'main.bicep') -Force).Count -gt 0 }), [Parameter(Mandatory = $false)] @@ -27,6 +27,7 @@ $script:convertedTemplates = @{} # Shared exception messages $script:bicepTemplateCompilationFailedException = "Unable to compile the main.bicep template's content. This can happen if there is an error in the template. Please check if you can run the command ``bicep build {0} --stdout | ConvertFrom-Json -AsHashtable``." # -f $templateFilePath +$script:jsonTemplateLoadFailedException = "Unable to load the main.json template's content. This can happen if there is an error in the template. Please check if you can run the command `Get-Content {0} -Raw | ConvertFrom-Json -AsHashtable`." # -f $templateFilePath $script:templateNotFoundException = 'No template file found in folder [{0}]' # -f $moduleFolderPath # Import any helper function used in this test script @@ -202,6 +203,13 @@ Describe 'Module tests' -Tag 'Module' { if (-not $templateContent) { throw ($bicepTemplateCompilationFailedException -f $templateFilePath) } + } elseIf (Test-Path (Join-Path $moduleFolderPath 'main.json')) { + $templateFilePath = Join-Path $moduleFolderPath 'main.json' + $templateContent = Get-Content $templateFilePath -Raw | ConvertFrom-Json -AsHashtable + + if (-not $templateContent) { + throw ($jsonTemplateLoadFailedException -f $templateFilePath) + } } else { throw ($templateNotFoundException -f $moduleFolderPath) } @@ -331,6 +339,13 @@ Describe 'Module tests' -Tag 'Module' { if (-not $templateContent) { throw ($bicepTemplateCompilationFailedException -f $templateFilePath) } + } elseIf (Test-Path (Join-Path $moduleFolderPath 'main.json')) { + $templateFilePath = Join-Path $moduleFolderPath 'main.json' + $templateContent = Get-Content $templateFilePath -Raw | ConvertFrom-Json -AsHashtable + + if (-not $templateContent) { + throw ($jsonTemplateLoadFailedException -f $templateFilePath) + } } else { throw ($templateNotFoundException -f $moduleFolderPath) } @@ -820,6 +835,7 @@ Describe 'Module tests' -Tag 'Module' { $incorrectOutputs | Should -BeNullOrEmpty } + # Update to work with nullable parameters It '[] All non-required parameters in template file should not have description that start with "Required.".' -TestCases $deploymentFolderTestCases { param ( [hashtable[]] $testFileTestCases, @@ -858,6 +874,13 @@ Describe 'Module tests' -Tag 'Module' { if (-not $templateContent) { throw ($bicepTemplateCompilationFailedException -f $templateFilePath) } + } elseIf (Test-Path (Join-Path $moduleFolderPath 'main.json')) { + $templateFilePath = Join-Path $moduleFolderPath 'main.json' + $templateContent = Get-Content $templateFilePath -Raw | ConvertFrom-Json -AsHashtable + + if (-not $templateContent) { + throw ($jsonTemplateLoadFailedException -f $templateFilePath) + } } else { throw ($templateNotFoundException -f $moduleFolderPath) } @@ -907,184 +930,6 @@ Describe 'Module tests' -Tag 'Module' { $templateFileContent.metadata.owner | Should -Not -BeNullOrEmpty } } - - Context 'User-defined-types tests' -Tag 'UDT' { - - $udtTestCases = [System.Collections.ArrayList] @() # General UDT tests (e.g. param should exist) - $udtSpecificTestCases = [System.Collections.ArrayList] @() # Specific UDT test cases for singular UDTs (e.g. tags) - foreach ($moduleFolderPath in $moduleFolderPaths) { - - $resourceTypeIdentifier = ($moduleFolderPath -split '[\/|\\]{1}avm[\/|\\]{1}(res|ptn)[\/|\\]{1}')[2] -replace '\\', '/' # avm/res// - - # For runtime purposes, we cache the compiled template in a hashtable that uses a formatted relative module path as a key - $moduleFolderPathKey = $moduleFolderPath.Replace('\', '/').Split('/avm/')[1].Trim('/').Replace('/', '-') - if (-not ($convertedTemplates.Keys -contains $moduleFolderPathKey)) { - if (Test-Path (Join-Path $moduleFolderPath 'main.bicep')) { - $templateFilePath = Join-Path $moduleFolderPath 'main.bicep' - $templateContent = bicep build $templateFilePath --stdout | ConvertFrom-Json -AsHashtable - - if (-not $templateContent) { - throw ($bicepTemplateCompilationFailedException -f $templateFilePath) - } - } else { - throw ($templateNotFoundException -f $moduleFolderPath) - } - $convertedTemplates[$moduleFolderPathKey] = @{ - templateContent = $templateContent - templateFilePath = $templateFilePath - } - } else { - $templateContent = $convertedTemplates[$moduleFolderPathKey].templateContent - $templateFilePath = $convertedTemplates[$moduleFolderPathKey].templateFilePath - } - - $udtSpecificTestCases += @{ - moduleFolderName = $resourceTypeIdentifier - templateFileContent = $templateContent - templateFileContentBicep = Get-Content $templateFilePath - } - - # Setting expected URL only for those that doen't have multiple different variants - $avmInterfaceSpecsTemplateBase = 'https://raw.githubusercontent.com/Azure/Azure-Verified-Modules/main/docs/static/includes/interfaces' - $avmInterfaceSpecsBase = 'https://azure.github.io/Azure-Verified-Modules/specs/shared/interfaces' - $udtCases = @( - @{ - parameterName = 'diagnosticSettings' - udtName = 'diagnosticSettingType' - link = "$avmInterfaceSpecsBase#diagnostic-settings" - } - @{ - parameterName = 'roleAssignments' - udtName = 'roleAssignmentType' - udtExpectedUrl = "$avmInterfaceSpecsTemplateBase/int.rbac.udt.schema.bicep" - link = "$avmInterfaceSpecsBase#role-assignments" - } - @{ - parameterName = 'lock' - udtName = 'lockType' - udtExpectedUrl = "$avmInterfaceSpecsTemplateBase/int.locks.udt.schema.bicep" - link = "$avmInterfaceSpecsBase#resource-locks" - } - @{ - parameterName = 'managedIdentities' - udtName = 'managedIdentitiesType' - link = "$avmInterfaceSpecsBase#managed-identities" - } - @{ - parameterName = 'privateEndpoints' - udtName = 'privateEndpointType' - link = "$avmInterfaceSpecsBase#private-endpoints" - } - @{ - parameterName = 'customerManagedKey' - udtName = 'customerManagedKeyType' - link = "$avmInterfaceSpecsBase#customer-managed-keys" - } - ) - - foreach ($udtCase in $udtCases) { - $udtTestCases += @{ - moduleFolderName = $resourceTypeIdentifier - templateFileContent = $templateContent - templateFileContentBicep = Get-Content $templateFilePath - parameterName = $udtCase.parameterName - udtName = $udtCase.udtName - expectedUdtUrl = $udtCase.udtExpectedUrl ? $udtCase.udtExpectedUrl : '' - link = $udtCase.link - } - } - } - - - It "[] If template has a parameter [], it should implement the user-defined type []" -TestCases $udtTestCases { - - param( - [hashtable] $templateFileContent, - [string[]] $templateFileContentBicep, - [string] $parameterName, - [string] $udtName, - [string] $expectedUdtUrl, - [string] $link - ) - - if ($templateFileContent.parameters.Keys -contains $parameterName) { - $templateFileContent.parameters.$parameterName.Keys | Should -Contain '$ref' -Because "the [$parameterName] parameter should use a user-defined type. For for information please review the [AVM Specs]($link)." - $templateFileContent.parameters.$parameterName.'$ref' | Should -Be "#/definitions/$udtName" -Because "the [$parameterName] parameter should use a user-defined type [$udtName]. For for information please review the [AVM Specs]($link)." - - if (-not [String]::IsNullOrEmpty($expectedUdtUrl)) { - $implementedSchemaStartIndex = $templateFileContentBicep.IndexOf("type $udtName = {") - $implementedSchemaEndIndex = $implementedSchemaStartIndex + 1 - while ($templateFileContentBicep[$implementedSchemaEndIndex] -notmatch '^\}.*' -and $implementedSchemaEndIndex -lt $templateFileContentBicep.Length) { - $implementedSchemaEndIndex++ - } - if ($implementedSchemaEndIndex -eq $templateFileContentBicep.Length) { - throw "Failed to identify [$udtName] user-defined type in template." - } - $implementedSchema = $templateFileContentBicep[$implementedSchemaStartIndex..$implementedSchemaEndIndex] - - $expectedSchemaFull = (Invoke-WebRequest -Uri $expectedUdtUrl).Content -split "\n" - $expectedSchemaStartIndex = $expectedSchemaFull.IndexOf("type $udtName = {") - $expectedSchemaEndIndex = $expectedSchemaStartIndex + 1 - while ($expectedSchemaFull[$expectedSchemaEndIndex] -notmatch '^\}.*' -and $expectedSchemaEndIndex -lt $expectedSchemaFull.Length) { - $expectedSchemaEndIndex++ - } - if ($expectedSchemaEndIndex -eq $expectedSchemaFull.Length) { - throw "Failed to identify [$udtName] user-defined type in expected schema at URL [$expectedUdtUrl]." - } - $expectedSchema = $expectedSchemaFull[$expectedSchemaStartIndex..$expectedSchemaEndIndex] - - $formattedDiff = @() - foreach ($finding in (Compare-Object $implementedSchema $expectedSchema)) { - if ($finding.SideIndicator -eq '=>') { - $formattedDiff += ('+ {0}' -f $finding.InputObject) - } elseif ($finding.SideIndicator -eq '<=') { - $formattedDiff += ('- {0}' -f $finding.InputObject) - } - } - - if ($formattedDiff.Count -gt 0) { - $warningMessage = "The implemented user-defined type is not the same as the expected user-defined type ({0}) defined in the AVM specs ({1}) and should not have diff`n{2}" -f $expectedUdtUrl, $link, ($formattedDiff | Out-String) - Write-Warning $warningMessage - - # Adding also to output to show in GitHub CI - $mdFormattedDiff = ($formattedDiff -join '
') -replace '\|', '\|' - $mdFormattedWarningMessage = "The implemented user-defined type is not the same as the expected [user-defined type]({0}) defined in the [AVM specs]({1}) and should not have diff
{2}
" -f $expectedUdtUrl, $link, $mdFormattedDiff - Write-Output @{ - Warning = $mdFormattedWarningMessage - } - } - } - } else { - Set-ItResult -Skipped -Because "the module template has no [$parameterName] parameter." - } - } - - It "[] If a UDT definition [managedIdentitiesType] exists and supports system-assigned-identities, the template should have an output for its principal ID." -TestCases $udtSpecificTestCases { - - param( - [hashtable] $templateFileContent - ) - - if ($templateFileContent.definitions.Keys -contains 'managedIdentitiesType' -and $templateFileContent.definitions.managedIdentitiesType.properties.keys -contains 'systemAssigned') { - $templateFileContent.outputs.Keys | Should -Contain 'systemAssignedMIPrincipalId' -Because 'The AVM specs require a this output. For for information please review the [AVM Specs](https://azure.github.io/Azure-Verified-Modules/specs/shared/interfaces#managed-identities).' - } else { - Set-ItResult -Skipped -Because "the module template has no [managedIdentitiesType] UDT definition or does not support system-assigned-identities." - } - } - - It "[] If a parameter [tags] exists it should be nullable." -TestCases $udtSpecificTestCases { - - param( - [hashtable] $templateFileContent - ) - - if ($templateFileContent.parameters.Keys -contains 'tags') { - $templateFileContent.parameters.tags.nullable | Should -Be $true -Because 'The AVM specs require a specific format. For for information please review the [AVM Specs](https://azure.github.io/Azure-Verified-Modules/specs/shared/interfaces#tags).' - } else { - Set-ItResult -Skipped -Because "the module template has no [tags] parameter." - } - } - } } Describe 'Test file tests' -Tag 'TestTemplate' { @@ -1101,7 +946,6 @@ Describe 'Test file tests' -Tag 'TestTemplate' { $resourceTypeIdentifier = ($moduleFolderPath -split '[\/|\\]{1}avm[\/|\\]{1}(res|ptn)[\/|\\]{1}')[2] -replace '\\', '/' # avm/res// $deploymentTestFileTestCases += @{ - testName = Split-Path (Split-Path $testFilePath) -Leaf testFilePath = $testFilePath testFileContent = $testFileContent moduleFolderName = $resourceTypeIdentifier @@ -1110,79 +954,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { } } - It "[] [] Bicep test deployment files should contain a parameter [serviceShort]" -TestCases $deploymentTestFileTestCases { - - param( - [object[]] $testFileContent - ) - ($testFileContent -match "^param serviceShort string = '(.*)$") | Should -Not -BeNullOrEmpty -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*''].' - } - - It "[] [] Bicep test deployment files in a [defaults] folder should have a parameter [serviceShort] with a value ending with [min]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]defaults[\\|\/].*' }) { - - param( - [object[]] $testFileContent - ) - - if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { - $Matches[1] | Should -BeLike "*min" - } else { - Set-ItResult -Skipped -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*min''] but it doesn''t.' - } - } - - It "[] [] Bicep test deployment files in a [max] folder should have a [serviceShort] parameter with a value ending with [max]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]max[\\|\/].*' }) { - - param( - [object[]] $testFileContent - ) - - if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { - $Matches[1] | Should -BeLike "*max" - } else { - Set-ItResult -Skipped -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*max''] but it doesn''t.' - } - } - - It "[] [] Bicep test deployment files in a [waf-aligned] folder should have a [serviceShort] parameter with a value ending with [waf]" -TestCases ($deploymentTestFileTestCases | Where-Object { $_.testFilePath -match '.*[\\|\/]waf\-aligned[\\|\/].*' }) { - - param( - [object[]] $testFileContent - ) - - if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { - $Matches[1] | Should -BeLike "*waf" - } else { - Set-ItResult -Skipped -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*waf''] but it doesn''t.' - } - } - - It "[] [] Bicep test deployment files should contain a metadata string [name]" -TestCases $deploymentTestFileTestCases { - - param( - [object[]] $testFileContent - ) - ($testFileContent | Out-String) | Should -Match "metadata name = .+" -Because 'Test cases should contain a metadata string [name] in the format `metadata name = ''This is one hell of a test name''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' - } - - It "[] [] Bicep test deployment files should contain a metadata string [description]" -TestCases $deploymentTestFileTestCases { - - param( - [object[]] $testFileContent - ) - ($testFileContent | Out-String) | Should -Match "metadata description = .+" -Because 'Test cases should contain a metadata string [description] in the format `metadata description = ''This is one hell of a description''` to be more descriptive. If provided, the tooling will automatically inject it into the module''s readme.md file.' - } - - It "[] [] Bicep test deployment files should contain a parameter [namePrefix] with value ['#_namePrefix_#']" -TestCases $deploymentTestFileTestCases { - - param( - [object[]] $testFileContent - ) - - ($testFileContent | Out-String) | Should -Match "param namePrefix string = '#_namePrefix_#'" -Because 'The test CI needs this value to ensure that deployed resources have unique names per fork.' - } - - It "[] [] Bicep test deployment files should invoke test like [`module testDeployment '../.*main.bicep' = {`]" -TestCases $deploymentTestFileTestCases { + It "[] Bicep test deployment files should invoke test like [`module testDeployment '../.*main.bicep' = {`]" -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent @@ -1193,7 +965,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { $testIndex -ne -1 | Should -Be $true -Because 'the module test invocation should be in the expected format to allow identification.' } - It '[] [] Bicep test deployment name should contain [`-test-`].' -TestCases $deploymentTestFileTestCases { + It '[] Bicep test deployment name should contain [`-test-`].' -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent @@ -1204,7 +976,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { $expectedNameFormat | Should -Be $true -Because 'the handle ''-test-'' should be part of the module test invocation''s resource name to allow identification.' } - It '[] [] Bicep test deployment should have parameter [`serviceShort`].' -TestCases $deploymentTestFileTestCases { + It '[] Bicep test deployment should have parameter [`serviceShort`].' -TestCases $deploymentTestFileTestCases { param( [object[]] $testFileContent @@ -1245,6 +1017,13 @@ Describe 'API version tests' -Tag 'ApiCheck' { if (-not $templateContent) { throw ($bicepTemplateCompilationFailedException -f $templateFilePath) } + } elseIf (Test-Path (Join-Path $moduleFolderPath 'main.json')) { + $templateFilePath = Join-Path $moduleFolderPath 'main.json' + $templateContent = Get-Content $templateFilePath -Raw | ConvertFrom-Json -AsHashtable + + if (-not $templateContent) { + throw ($jsonTemplateLoadFailedException -f $templateFilePath) + } } else { throw ($templateNotFoundException -f $moduleFolderPath) } @@ -1389,4 +1168,4 @@ Describe 'API version tests' -Tag 'ApiCheck' { } } } -} +} \ No newline at end of file From 31213359a56dd36e38e4afc6b6a9537f9534ee16 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Tue, 14 Nov 2023 09:43:39 +0100 Subject: [PATCH 22/52] Update to latest --- .../staticValidation/compliance/Set-PesterGitHubOutput.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 index 3563bc5f4f..38f43808ee 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 @@ -293,4 +293,4 @@ function Set-PesterGitHubOutput { $null = New-Item -Path $OutputFilePath -Force -Value ($fileContent | Out-String) } Write-Verbose "Create results file [$outputFilePath]" -} \ No newline at end of file +} From 3d4f5c6bef1e492cd25a6d0c334088ab8afa49b7 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sun, 26 Nov 2023 11:18:23 +0100 Subject: [PATCH 23/52] Added pipeline to main for testing --- .../workflows/avm.platform.publish.tag.yml | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 .github/workflows/avm.platform.publish.tag.yml diff --git a/.github/workflows/avm.platform.publish.tag.yml b/.github/workflows/avm.platform.publish.tag.yml new file mode 100644 index 0000000000..e81a3c1c78 --- /dev/null +++ b/.github/workflows/avm.platform.publish.tag.yml @@ -0,0 +1,63 @@ +name: "Publish AVM module with tag" + +on: + workflow_dispatch: + inputs: + tag: + description: "The git tag of the module to publish." + required: true + type: string + +permissions: + id-token: write + contents: read + +jobs: + job_publish_module_with_tag: + runs-on: ubuntu-latest + name: "Publish module with tag" + steps: + - name: Checkout tag + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.tag }} + + - name: Log in to Azure + uses: azure/login@v1 + with: + client-id: ${{ env.PUBLISH_CLIENT_ID }} + tenant-id: ${{ env.PUBLISH_TENANT_ID }} + subscription-id: ${{ env.PUBLISH_SUBSCRIPTION_ID }} + + # Adding a step to explicitly install the latest Bicep CLI because there is + # always a delay in updating Bicep CLI in the job runner environments. + - name: Install the latest Bicep CLI + shell: bash + run: | + curl -Lo bicep https://github.com/Azure/bicep/releases/latest/download/bicep-linux-x64 + chmod +x ./bicep + sudo mv ./bicep /usr/local/bin/bicep + bicep --version + + - name: "Publish tagged module to public bicep registry" + uses: azure/powershell@v1 + with: + azPSVersion: "latest" + inlineScript: | + # Grouping task logs + Write-Output '::group::Publish tagged module to public bicep registry' + + # Load used functions + . (Join-Path $env:GITHUB_WORKSPACE 'avm' 'utilities' 'pipelines' 'publish' 'Publish-ModuleFromTagToPBR.ps1') + + $functionInput = @{ + ModuleReleaseTagName = '${{ github.event.inputs.tag }}' + PublicRegistryServer = ConvertTo-SecureString '${{ env.PUBLISH_REGISTRY_SERVER }}' -AsPlainText -Force + } + + Write-Verbose "Invoke function with" -Verbose + Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose + + Publish-ModuleFromTagToPBR @functionInput -Verbose + + Write-Output '::endgroup::' \ No newline at end of file From 917a7614c603ffd3c74e81992dabcc292aa0959a Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Mon, 4 Dec 2023 10:29:17 +0100 Subject: [PATCH 24/52] TEst disable pipe --- .github/workflows/test.workflow.yml | 51 +++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/test.workflow.yml diff --git a/.github/workflows/test.workflow.yml b/.github/workflows/test.workflow.yml new file mode 100644 index 0000000000..acad22ebf7 --- /dev/null +++ b/.github/workflows/test.workflow.yml @@ -0,0 +1,51 @@ +name: 'avm.platform.toggle-avm-workflows' + +on: + workflow_dispatch: + inputs: + workMode: + type: choice + description: "Enable or disable workflows" + required: true + options: + - "enable" + - "disable" + default: "disable" + includePattern: + type: string + description: "RegEx which workflows are included" + required: false + default: "avm\\.(?:res|ptn)" + excludePattern: + type: string + description: "RegEx which workflows are excluded" + required: false + default: "^$" + +jobs: + toggle-avm-workflows: + if: github.repository != 'Azure/bicep-registry-modules' + runs-on: ubuntu-latest + steps: + - name: 'Checkout' + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - env: + GH_TOKEN: ${{ github.token }} + name: ${{ inputs.workMode }} AVM workflows + shell: pwsh + run: | + $repo = "${{ github.repository_owner }}/${{ github.event.repository.name }}" + $workflows = gh workflow list --repo $repo --all --json 'name,state,id' | ConvertFrom-Json -Depth 100 + $relevantWorkflows = $workflows | Where-Object { + $_.name -match "${{ inputs.includePattern }}" -and $_.name -notmatch "${{ inputs.excludePattern }}" + } + + foreach ($workflow in $relevantWorkflows) { + if (("${{ inputs.workMode }}" -eq "disable" -and $workflow.state -eq 'active') -or ("${{ inputs.workMode }}" -eq "enable" -and $workflow.state -ne 'active')) + { + Write-Verbose "${{ inputs.workMode }} $($workflow.name)" -Verbose + gh workflow ${{ inputs.workMode }} $workflow.id --repo $repo + } + } \ No newline at end of file From feb981ece77a7c31e5e80931a993613846bfe628 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Mon, 4 Dec 2023 10:32:18 +0100 Subject: [PATCH 25/52] Update to latest --- .../workflows/avm.platform.publish.tag.yml | 63 ------------------- .github/workflows/test.workflow.yml | 51 --------------- 2 files changed, 114 deletions(-) delete mode 100644 .github/workflows/avm.platform.publish.tag.yml delete mode 100644 .github/workflows/test.workflow.yml diff --git a/.github/workflows/avm.platform.publish.tag.yml b/.github/workflows/avm.platform.publish.tag.yml deleted file mode 100644 index e81a3c1c78..0000000000 --- a/.github/workflows/avm.platform.publish.tag.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: "Publish AVM module with tag" - -on: - workflow_dispatch: - inputs: - tag: - description: "The git tag of the module to publish." - required: true - type: string - -permissions: - id-token: write - contents: read - -jobs: - job_publish_module_with_tag: - runs-on: ubuntu-latest - name: "Publish module with tag" - steps: - - name: Checkout tag - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.tag }} - - - name: Log in to Azure - uses: azure/login@v1 - with: - client-id: ${{ env.PUBLISH_CLIENT_ID }} - tenant-id: ${{ env.PUBLISH_TENANT_ID }} - subscription-id: ${{ env.PUBLISH_SUBSCRIPTION_ID }} - - # Adding a step to explicitly install the latest Bicep CLI because there is - # always a delay in updating Bicep CLI in the job runner environments. - - name: Install the latest Bicep CLI - shell: bash - run: | - curl -Lo bicep https://github.com/Azure/bicep/releases/latest/download/bicep-linux-x64 - chmod +x ./bicep - sudo mv ./bicep /usr/local/bin/bicep - bicep --version - - - name: "Publish tagged module to public bicep registry" - uses: azure/powershell@v1 - with: - azPSVersion: "latest" - inlineScript: | - # Grouping task logs - Write-Output '::group::Publish tagged module to public bicep registry' - - # Load used functions - . (Join-Path $env:GITHUB_WORKSPACE 'avm' 'utilities' 'pipelines' 'publish' 'Publish-ModuleFromTagToPBR.ps1') - - $functionInput = @{ - ModuleReleaseTagName = '${{ github.event.inputs.tag }}' - PublicRegistryServer = ConvertTo-SecureString '${{ env.PUBLISH_REGISTRY_SERVER }}' -AsPlainText -Force - } - - Write-Verbose "Invoke function with" -Verbose - Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose - - Publish-ModuleFromTagToPBR @functionInput -Verbose - - Write-Output '::endgroup::' \ No newline at end of file diff --git a/.github/workflows/test.workflow.yml b/.github/workflows/test.workflow.yml deleted file mode 100644 index acad22ebf7..0000000000 --- a/.github/workflows/test.workflow.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: 'avm.platform.toggle-avm-workflows' - -on: - workflow_dispatch: - inputs: - workMode: - type: choice - description: "Enable or disable workflows" - required: true - options: - - "enable" - - "disable" - default: "disable" - includePattern: - type: string - description: "RegEx which workflows are included" - required: false - default: "avm\\.(?:res|ptn)" - excludePattern: - type: string - description: "RegEx which workflows are excluded" - required: false - default: "^$" - -jobs: - toggle-avm-workflows: - if: github.repository != 'Azure/bicep-registry-modules' - runs-on: ubuntu-latest - steps: - - name: 'Checkout' - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - env: - GH_TOKEN: ${{ github.token }} - name: ${{ inputs.workMode }} AVM workflows - shell: pwsh - run: | - $repo = "${{ github.repository_owner }}/${{ github.event.repository.name }}" - $workflows = gh workflow list --repo $repo --all --json 'name,state,id' | ConvertFrom-Json -Depth 100 - $relevantWorkflows = $workflows | Where-Object { - $_.name -match "${{ inputs.includePattern }}" -and $_.name -notmatch "${{ inputs.excludePattern }}" - } - - foreach ($workflow in $relevantWorkflows) { - if (("${{ inputs.workMode }}" -eq "disable" -and $workflow.state -eq 'active') -or ("${{ inputs.workMode }}" -eq "enable" -and $workflow.state -ne 'active')) - { - Write-Verbose "${{ inputs.workMode }} $($workflow.name)" -Verbose - gh workflow ${{ inputs.workMode }} $workflow.id --repo $repo - } - } \ No newline at end of file From f4136ecc4bc806790f908046979c3045f3cb0e5e Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Fri, 22 Dec 2023 10:47:59 +0100 Subject: [PATCH 26/52] Added SA workflow --- .../avm.res.storage.storage-account.yml | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 .github/workflows/avm.res.storage.storage-account.yml diff --git a/.github/workflows/avm.res.storage.storage-account.yml b/.github/workflows/avm.res.storage.storage-account.yml new file mode 100644 index 0000000000..061ef0be68 --- /dev/null +++ b/.github/workflows/avm.res.storage.storage-account.yml @@ -0,0 +1,83 @@ +name: "avm.res.storage.storage-account" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.storage.storage-account.yml" + - "avm/res/storage/storage-account/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/storage/storage-account" + workflowPath: ".github/workflows/avm.res.storage.storage-account.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-20.04 + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit From e55e73257d0fcf23b3c8bae557fbcf54e5ac5ea0 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Mon, 1 Jan 2024 19:15:54 +0100 Subject: [PATCH 27/52] Added workflow --- ....virtual-machine-images.image-template.yml | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 .github/workflows/avm.res.virtual-machine-images.image-template.yml diff --git a/.github/workflows/avm.res.virtual-machine-images.image-template.yml b/.github/workflows/avm.res.virtual-machine-images.image-template.yml new file mode 100644 index 0000000000..08c03c7560 --- /dev/null +++ b/.github/workflows/avm.res.virtual-machine-images.image-template.yml @@ -0,0 +1,83 @@ +name: "avm.res.resource-graph.query" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.virtual-machine-images.image-template.yml" + - "avm/res/virtual-machine-images/image-template/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/virtual-machine-images/image-template" + workflowPath: ".github/workflows/avm.res.virtual-machine-images.image-template.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-20.04 + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit From 5c6aa5e64d2e7f6ac3c9a7e1522ac8590b019f30 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Mon, 1 Jan 2024 19:16:30 +0100 Subject: [PATCH 28/52] Update to latest --- .../workflows/avm.res.virtual-machine-images.image-template.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/avm.res.virtual-machine-images.image-template.yml b/.github/workflows/avm.res.virtual-machine-images.image-template.yml index 08c03c7560..37bb62af5e 100644 --- a/.github/workflows/avm.res.virtual-machine-images.image-template.yml +++ b/.github/workflows/avm.res.virtual-machine-images.image-template.yml @@ -1,4 +1,4 @@ -name: "avm.res.resource-graph.query" +name: "avm.res.virtual-machine-images.image-template" on: schedule: From 4012fdd51e0f4a7e1fd34e62abf40b97794dfd26 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Thu, 18 Jan 2024 21:16:44 +0100 Subject: [PATCH 29/52] Update to latest --- .github/workflows/avm.res.storage.storage-account.yml | 2 +- .../workflows/avm.res.virtual-machine-images.image-template.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/avm.res.storage.storage-account.yml b/.github/workflows/avm.res.storage.storage-account.yml index 061ef0be68..d6c72b0bdd 100644 --- a/.github/workflows/avm.res.storage.storage-account.yml +++ b/.github/workflows/avm.res.storage.storage-account.yml @@ -44,7 +44,7 @@ jobs: # Initialize pipeline # ########################### job_initialize_pipeline: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest name: "Initialize pipeline" steps: - name: "Checkout" diff --git a/.github/workflows/avm.res.virtual-machine-images.image-template.yml b/.github/workflows/avm.res.virtual-machine-images.image-template.yml index 37bb62af5e..63fe597668 100644 --- a/.github/workflows/avm.res.virtual-machine-images.image-template.yml +++ b/.github/workflows/avm.res.virtual-machine-images.image-template.yml @@ -44,7 +44,7 @@ jobs: # Initialize pipeline # ########################### job_initialize_pipeline: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest name: "Initialize pipeline" steps: - name: "Checkout" From 3f225f9214821b8f18271db355d6f650b26c678c Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Tue, 23 Jan 2024 19:48:09 +0100 Subject: [PATCH 30/52] Removed outdated metadata --- avm/res/compute/ssh-public-key/README.md | 2 -- .../ssh-public-key/tests/e2e/defaults/main.test.bicep | 5 +---- avm/res/key-vault/vault/README.md | 2 -- avm/res/key-vault/vault/tests/e2e/defaults/main.test.bicep | 5 +---- avm/res/kubernetes-configuration/extension/README.md | 2 -- .../extension/tests/e2e/defaults/main.test.bicep | 5 +---- .../kubernetes-configuration/flux-configuration/README.md | 2 -- .../flux-configuration/tests/e2e/defaults/main.test.bicep | 5 +---- avm/res/logic/workflow/README.md | 2 -- avm/res/logic/workflow/tests/e2e/defaults/main.test.bicep | 5 +---- avm/res/network/dns-forwarding-ruleset/README.md | 2 -- .../tests/e2e/defaults/main.test.bicep | 5 +---- avm/res/network/dns-resolver/README.md | 2 -- .../network/dns-resolver/tests/e2e/defaults/main.test.bicep | 5 +---- avm/res/network/private-dns-zone/README.md | 2 -- .../private-dns-zone/tests/e2e/defaults/main.test.bicep | 5 +---- avm/res/network/private-endpoint/README.md | 2 -- .../private-endpoint/tests/e2e/defaults/main.test.bicep | 5 +---- avm/res/network/public-ip-address/README.md | 2 -- .../public-ip-address/tests/e2e/defaults/main.test.bicep | 5 +---- .../deployment-script/tests/e2e/defaults/main.test.bicep | 5 +---- 21 files changed, 11 insertions(+), 64 deletions(-) diff --git a/avm/res/compute/ssh-public-key/README.md b/avm/res/compute/ssh-public-key/README.md index 6f71b01603..61009d7cbc 100644 --- a/avm/res/compute/ssh-public-key/README.md +++ b/avm/res/compute/ssh-public-key/README.md @@ -36,8 +36,6 @@ The following section provides usage examples for the module, which were used to ### Example 1: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -
diff --git a/avm/res/compute/ssh-public-key/tests/e2e/defaults/main.test.bicep b/avm/res/compute/ssh-public-key/tests/e2e/defaults/main.test.bicep index a0aa5bb9c3..4c413e5147 100644 --- a/avm/res/compute/ssh-public-key/tests/e2e/defaults/main.test.bicep +++ b/avm/res/compute/ssh-public-key/tests/e2e/defaults/main.test.bicep @@ -1,10 +1,7 @@ targetScope = 'subscription' metadata name = 'Using only defaults' -metadata description = ''' -This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -''' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' // ========== // // Parameters // // ========== // diff --git a/avm/res/key-vault/vault/README.md b/avm/res/key-vault/vault/README.md index 8baf02b7f8..80f7541711 100644 --- a/avm/res/key-vault/vault/README.md +++ b/avm/res/key-vault/vault/README.md @@ -41,8 +41,6 @@ The following section provides usage examples for the module, which were used to ### Example 1: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -
diff --git a/avm/res/key-vault/vault/tests/e2e/defaults/main.test.bicep b/avm/res/key-vault/vault/tests/e2e/defaults/main.test.bicep index 8297b5cf1d..5206ce36da 100644 --- a/avm/res/key-vault/vault/tests/e2e/defaults/main.test.bicep +++ b/avm/res/key-vault/vault/tests/e2e/defaults/main.test.bicep @@ -1,10 +1,7 @@ targetScope = 'subscription' metadata name = 'Using only defaults' -metadata description = ''' -This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -''' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' // ========== // // Parameters // diff --git a/avm/res/kubernetes-configuration/extension/README.md b/avm/res/kubernetes-configuration/extension/README.md index 7d56403794..e22acb4757 100644 --- a/avm/res/kubernetes-configuration/extension/README.md +++ b/avm/res/kubernetes-configuration/extension/README.md @@ -34,8 +34,6 @@ The following section provides usage examples for the module, which were used to ### Example 1: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -
diff --git a/avm/res/kubernetes-configuration/extension/tests/e2e/defaults/main.test.bicep b/avm/res/kubernetes-configuration/extension/tests/e2e/defaults/main.test.bicep index 27e1da7346..8297beab10 100644 --- a/avm/res/kubernetes-configuration/extension/tests/e2e/defaults/main.test.bicep +++ b/avm/res/kubernetes-configuration/extension/tests/e2e/defaults/main.test.bicep @@ -1,10 +1,7 @@ targetScope = 'subscription' metadata name = 'Using only defaults' -metadata description = ''' -This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -''' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' // ========== // // Parameters // // ========== // diff --git a/avm/res/kubernetes-configuration/flux-configuration/README.md b/avm/res/kubernetes-configuration/flux-configuration/README.md index 75e174b03b..313b025b8f 100644 --- a/avm/res/kubernetes-configuration/flux-configuration/README.md +++ b/avm/res/kubernetes-configuration/flux-configuration/README.md @@ -33,8 +33,6 @@ The following section provides usage examples for the module, which were used to ### Example 1: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -
diff --git a/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/defaults/main.test.bicep b/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/defaults/main.test.bicep index 4b195f6b1a..5e44b0a2e9 100644 --- a/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/defaults/main.test.bicep +++ b/avm/res/kubernetes-configuration/flux-configuration/tests/e2e/defaults/main.test.bicep @@ -1,10 +1,7 @@ targetScope = 'subscription' metadata name = 'Using only defaults' -metadata description = ''' -This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -''' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' // ========== // // Parameters // diff --git a/avm/res/logic/workflow/README.md b/avm/res/logic/workflow/README.md index 6233d8aa19..552b5adce5 100644 --- a/avm/res/logic/workflow/README.md +++ b/avm/res/logic/workflow/README.md @@ -36,8 +36,6 @@ The following section provides usage examples for the module, which were used to ### Example 1: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -
diff --git a/avm/res/logic/workflow/tests/e2e/defaults/main.test.bicep b/avm/res/logic/workflow/tests/e2e/defaults/main.test.bicep index c48184ea65..c7cdd8e3aa 100644 --- a/avm/res/logic/workflow/tests/e2e/defaults/main.test.bicep +++ b/avm/res/logic/workflow/tests/e2e/defaults/main.test.bicep @@ -1,10 +1,7 @@ targetScope = 'subscription' metadata name = 'Using only defaults' -metadata description = ''' -This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -''' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' // ========== // // Parameters // diff --git a/avm/res/network/dns-forwarding-ruleset/README.md b/avm/res/network/dns-forwarding-ruleset/README.md index 2f78e29c7e..76cf692df8 100644 --- a/avm/res/network/dns-forwarding-ruleset/README.md +++ b/avm/res/network/dns-forwarding-ruleset/README.md @@ -36,8 +36,6 @@ The following section provides usage examples for the module, which were used to ### Example 1: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -
diff --git a/avm/res/network/dns-forwarding-ruleset/tests/e2e/defaults/main.test.bicep b/avm/res/network/dns-forwarding-ruleset/tests/e2e/defaults/main.test.bicep index 937fabd992..c6fc0e9319 100644 --- a/avm/res/network/dns-forwarding-ruleset/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/dns-forwarding-ruleset/tests/e2e/defaults/main.test.bicep @@ -1,10 +1,7 @@ targetScope = 'subscription' metadata name = 'Using only defaults' -metadata description = ''' -This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -''' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' // ========== // // Parameters // diff --git a/avm/res/network/dns-resolver/README.md b/avm/res/network/dns-resolver/README.md index 2513e2ceb9..ba788edc3a 100644 --- a/avm/res/network/dns-resolver/README.md +++ b/avm/res/network/dns-resolver/README.md @@ -36,8 +36,6 @@ The following section provides usage examples for the module, which were used to ### Example 1: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -
diff --git a/avm/res/network/dns-resolver/tests/e2e/defaults/main.test.bicep b/avm/res/network/dns-resolver/tests/e2e/defaults/main.test.bicep index aff32456f8..171177a2c7 100644 --- a/avm/res/network/dns-resolver/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/dns-resolver/tests/e2e/defaults/main.test.bicep @@ -1,10 +1,7 @@ targetScope = 'subscription' metadata name = 'Using only defaults' -metadata description = ''' -This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -''' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' // ========== // // Parameters // diff --git a/avm/res/network/private-dns-zone/README.md b/avm/res/network/private-dns-zone/README.md index 1159c1dddc..633c3b8e3e 100644 --- a/avm/res/network/private-dns-zone/README.md +++ b/avm/res/network/private-dns-zone/README.md @@ -43,8 +43,6 @@ The following section provides usage examples for the module, which were used to ### Example 1: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -
diff --git a/avm/res/network/private-dns-zone/tests/e2e/defaults/main.test.bicep b/avm/res/network/private-dns-zone/tests/e2e/defaults/main.test.bicep index 0c43e4878b..1edd244cee 100644 --- a/avm/res/network/private-dns-zone/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/private-dns-zone/tests/e2e/defaults/main.test.bicep @@ -1,10 +1,7 @@ targetScope = 'subscription' metadata name = 'Using only defaults' -metadata description = ''' -This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -''' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' // ========== // // Parameters // diff --git a/avm/res/network/private-endpoint/README.md b/avm/res/network/private-endpoint/README.md index f813411f2d..0721d58688 100644 --- a/avm/res/network/private-endpoint/README.md +++ b/avm/res/network/private-endpoint/README.md @@ -35,8 +35,6 @@ The following section provides usage examples for the module, which were used to ### Example 1: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -
diff --git a/avm/res/network/private-endpoint/tests/e2e/defaults/main.test.bicep b/avm/res/network/private-endpoint/tests/e2e/defaults/main.test.bicep index 14c6f0e2d9..d07daeae23 100644 --- a/avm/res/network/private-endpoint/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/private-endpoint/tests/e2e/defaults/main.test.bicep @@ -1,10 +1,7 @@ targetScope = 'subscription' metadata name = 'Using only defaults' -metadata description = ''' -This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -''' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' // ========== // // Parameters // diff --git a/avm/res/network/public-ip-address/README.md b/avm/res/network/public-ip-address/README.md index dfdb4ca6be..dc1843b3c5 100644 --- a/avm/res/network/public-ip-address/README.md +++ b/avm/res/network/public-ip-address/README.md @@ -35,8 +35,6 @@ The following section provides usage examples for the module, which were used to ### Example 1: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -
diff --git a/avm/res/network/public-ip-address/tests/e2e/defaults/main.test.bicep b/avm/res/network/public-ip-address/tests/e2e/defaults/main.test.bicep index b4e293d5f8..1c2dd866e5 100644 --- a/avm/res/network/public-ip-address/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/public-ip-address/tests/e2e/defaults/main.test.bicep @@ -1,10 +1,7 @@ targetScope = 'subscription' metadata name = 'Using only defaults' -metadata description = ''' -This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -''' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' // ========== // // Parameters // diff --git a/avm/res/resources/deployment-script/tests/e2e/defaults/main.test.bicep b/avm/res/resources/deployment-script/tests/e2e/defaults/main.test.bicep index 926bc535be..f1f7fbdb3e 100644 --- a/avm/res/resources/deployment-script/tests/e2e/defaults/main.test.bicep +++ b/avm/res/resources/deployment-script/tests/e2e/defaults/main.test.bicep @@ -1,10 +1,7 @@ targetScope = 'subscription' metadata name = 'Using only defaults' -metadata description = ''' -This instance deploys the module with the minimum set of required parameters. -> **Note:** The test currently implements additional non-required parameters to cater for a test-specific limitation. -''' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' // ========== // // Parameters // From f2bd197f65c6bb2f81183e720d71c3037a79e195 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Tue, 23 Jan 2024 19:51:52 +0100 Subject: [PATCH 31/52] Update to latest --- ....virtual-machine-images.image-template.yml | 83 ------------------- 1 file changed, 83 deletions(-) delete mode 100644 .github/workflows/avm.res.virtual-machine-images.image-template.yml diff --git a/.github/workflows/avm.res.virtual-machine-images.image-template.yml b/.github/workflows/avm.res.virtual-machine-images.image-template.yml deleted file mode 100644 index 63fe597668..0000000000 --- a/.github/workflows/avm.res.virtual-machine-images.image-template.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: "avm.res.virtual-machine-images.image-template" - -on: - schedule: - - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) - workflow_dispatch: - inputs: - staticValidation: - type: boolean - description: "Execute static validation" - required: false - default: true - deploymentValidation: - type: boolean - description: "Execute deployment validation" - required: false - default: true - removeDeployment: - type: boolean - description: "Remove deployed module" - required: false - default: true - - push: - branches: - - main - paths: - - ".github/actions/templates/avm-**" - - ".github/workflows/avm.template.module.yml" - - ".github/workflows/avm.res.virtual-machine-images.image-template.yml" - - "avm/res/virtual-machine-images/image-template/**" - - "avm/utilities/pipelines/**" - - "!*/**/README.md" - -env: - modulePath: "avm/res/virtual-machine-images/image-template" - workflowPath: ".github/workflows/avm.res.virtual-machine-images.image-template.yml" - -concurrency: - group: ${{ github.workflow }} - -jobs: - ########################### - # Initialize pipeline # - ########################### - job_initialize_pipeline: - runs-on: ubuntu-latest - name: "Initialize pipeline" - steps: - - name: "Checkout" - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: "Set input parameters to output variables" - id: get-workflow-param - uses: ./.github/actions/templates/avm-getWorkflowInput - with: - workflowPath: "${{ env.workflowPath}}" - - name: "Get module test file paths" - id: get-module-test-file-paths - uses: ./.github/actions/templates/avm-getModuleTestFiles - with: - modulePath: "${{ env.modulePath }}" - outputs: - workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} - moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} - psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} - modulePath: "${{ env.modulePath }}" - - ############################## - # Call reusable workflow # - ############################## - call-workflow-passing-data: - name: "Run" - needs: - - job_initialize_pipeline - uses: ./.github/workflows/avm.template.module.yml - with: - workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" - moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" - psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" - modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" - secrets: inherit From 9d063cebdd15c84d6ae6bcc64802fce41e39ca7b Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Mon, 29 Jan 2024 18:03:01 +0100 Subject: [PATCH 32/52] Refereshed docs --- avm/res/resources/deployment-script/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/avm/res/resources/deployment-script/README.md b/avm/res/resources/deployment-script/README.md index 69e3012079..c71dd592e5 100644 --- a/avm/res/resources/deployment-script/README.md +++ b/avm/res/resources/deployment-script/README.md @@ -135,8 +135,6 @@ module deploymentScript 'br/public:avm/res/resources/deployment-script: ### Example 2: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. -> **Note:** In this scenario, In this scenario, the `Storage File Data Privileged Contributor` role needs to be assigned to the user-assigned managed identity and the deployment principal needs to have permissions to list the storage account keys. -
From c2637f384edb9d36b4627b535d74a0576b39b31a Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Fri, 16 Feb 2024 22:24:29 +0100 Subject: [PATCH 33/52] Update to latest --- .../avm-validateModuleDeployment/action.yml | 88 +++++++++++++++++-- .../e2e/private-endpoint/main.test.bicep | 2 + .../tests/nestedLevel.tests.ps1 | 24 +++++ .../e2e/private-endpoint/topLevel.tests.ps1 | 41 +++++++++ 4 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 create mode 100644 avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 diff --git a/.github/actions/templates/avm-validateModuleDeployment/action.yml b/.github/actions/templates/avm-validateModuleDeployment/action.yml index 7fec4c6374..23b09ac479 100644 --- a/.github/actions/templates/avm-validateModuleDeployment/action.yml +++ b/.github/actions/templates/avm-validateModuleDeployment/action.yml @@ -264,14 +264,9 @@ runs: Write-Output ('{0}={1}' -f 'deploymentNames', ($res.deploymentNames | ConvertTo-Json -Compress)) >> $env:GITHUB_OUTPUT # Populate further outputs - $deploymentOutputHashTable = @{} + $deploymentOutput = $res.deploymentOutput | ConvertTo-Json -Depth 99 -Compress + Write-Output ('{0}={1}' -f 'deploymentOutput', $deploymentOutput) >> $env:GITHUB_OUTPUT - foreach ($outputKey in $res.deploymentOutput.Keys) { - Write-Output ('{0}={1}' -f 'outputKey', $res.deploymentOutput[$outputKey].Value) >> $env:GITHUB_OUTPUT - $deploymentOutputHashTable.add($outputKey, $res.deploymentOutput[$outputKey].Value) - } - - $deploymentOutput = $deploymentOutputHashTable | ConvertTo-Json -Compress -Depth 100 Write-Verbose "Deployment output: $deploymentOutput" -Verbose if ($res.ContainsKey('exception')) { @@ -281,6 +276,85 @@ runs: Write-Output '::endgroup::' + # [Post-Deployment test] task(s) + # ------------------------------ + - name: "Run post-deployment Pester tests" + id: pester_run_step + shell: pwsh + run: | + # Grouping task logs + Write-Output '::group::Run Pester tests' + + # Load used functions + . (Join-Path $env:GITHUB_WORKSPACE 'avm' 'utilities' 'pipelines' 'staticValidation' 'compliance' 'Set-PesterGitHubOutput.ps1') + + # Set repo root path + $repoRootPath = $env:GITHUB_WORKSPACE + + $moduleTestFilePath = Join-Path $env:GITHUB_WORKSPACE '${{ inputs.templateFilePath }}' + $moduleTestFolderPath = Split-Path $moduleTestFilePath + $moduleTestFolderName = Split-Path $moduleTestFolderPath -Leaf + + $deploymentOutputs = $env:deploymentOutput | ConvertFrom-Json -AsHashTable + + # --------------------- # + # Invoke Pester test(s) # + # --------------------- # + + $pesterConfiguration = @{ + Run = @{ + Container = New-PesterContainer -Path $moduleTestFolderPath -Data @{ + DeploymentOutputs = $deploymentOutputs # Passing in in case we want to directly validate data via the deployment's output + ModuleTestFolderPath = $moduleTestFolderPath # Passing in in case we want to access any data in the test folder / files + } + PassThru = $true + } + Output = @{ + Verbosity = 'Detailed' + } + } + + Write-Verbose 'Invoke test with' -Verbose + Write-Verbose ($pesterConfiguration | ConvertTo-Json -Depth 4 | Out-String) -Verbose + + $testResults = Invoke-Pester -Configuration $pesterConfiguration + + # ----------------------------------------- # + # Create formatted Pester Test Results File # + # ----------------------------------------- # + + $functionInput = @{ + PesterTestResults = $testResults + OutputFilePath = Join-Path $env:GITHUB_WORKSPACE 'avm' "$moduleTestFolderName-Pester-output.md" + GitHubRepository = $env:GITHUB_REPOSITORY + BranchName = $env:GITHUB_REF + } + + Write-Verbose 'Invoke Pester formatting function with' -Verbose + Write-Verbose ($functionInput | ConvertTo-Json -Depth 0 | Out-String) -Verbose + + Set-PesterGitHubOutput @functionInput -Verbose + + Write-Output ('{0}={1}' -f 'formattedPesterResultsPath', $functionInput.outputFilePath) >> $env:GITHUB_OUTPUT + + - name: "Output to GitHub job summaries" + if: always() + shell: pwsh + run: | + # Grouping task logs + Write-Output '::group::Output to GitHub job summaries' + + $mdPesterOutputFilePath = '${{ steps.pester_run_step.outputs.formattedPesterResultsPath }}' + + if (-not (Test-Path $mdPesterOutputFilePath)) { + Write-Warning ('Input file [{0}] not found. Please check if the previous task threw an error and try again.' -f $mdPesterOutputFilePath) + } else { + Get-Content $mdPesterOutputFilePath >> $env:GITHUB_STEP_SUMMARY + Write-Verbose ('Successfully printed out file [{0}] to Job Summaries' -f $mdPesterOutputFilePath) -Verbose + } + + Write-Output '::endgroup::' + # [Deployment removal] task(s) # ---------------------------- - name: "Remove deployed resources" diff --git a/avm/res/key-vault/vault/tests/e2e/private-endpoint/main.test.bicep b/avm/res/key-vault/vault/tests/e2e/private-endpoint/main.test.bicep index 6694323ecc..c168da6e59 100644 --- a/avm/res/key-vault/vault/tests/e2e/private-endpoint/main.test.bicep +++ b/avm/res/key-vault/vault/tests/e2e/private-endpoint/main.test.bicep @@ -99,3 +99,5 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' enablePurgeProtection: false } }] + +output resourceId string = testDeployment[1].outputs.resourceId diff --git a/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 b/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 new file mode 100644 index 0000000000..4c93e2070d --- /dev/null +++ b/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 @@ -0,0 +1,24 @@ +###################################### +## Additional post-deployment tests ## +###################################### +## +## You can add any custom post-deployment validation tests you want here, or add them spread accross multiple test files in the test case folder. +## +########################### + +param ( + [Parameter(Mandatory)] + [hashtable] $DeploymentOutputs +) + +Describe 'Validate key vault' { + + It 'Public endpoint disabled' { + + $keyVaultResourceId = $DeploymentOutputs.resourceId + + $deployedResource = Get-AzResource -ResourceId $keyVaultResourceId + + $deployedResource.Properties.publicNetworkAccess | Should -Be 'Disabled' + } +} \ No newline at end of file diff --git a/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 b/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 new file mode 100644 index 0000000000..da295343ac --- /dev/null +++ b/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 @@ -0,0 +1,41 @@ +###################################### +## Additional post-deployment tests ## +###################################### +## +## You can add any custom post-deployment validation tests you want here, or add them spread accross multiple test files in the test case folder. +## +########################### + +param ( + [Parameter(Mandatory)] + [string] $ModuleTestFolderPath, + + [Parameter(Mandatory)] + [hashtable] $DeploymentOutputs +) + +Describe 'Validate private endpoint deployment' { + + Context 'Validate sucessful deployment' { + + It 'Private endpoints should be deployed' { + + $keyVaultResourceId = $DeploymentOutputs.resourceId + $testResourceGroup = ($keyVaultResourceId -split '\/')[4] + $deployedPrivateEndpoints = Get-AzPrivateEndpoint -ResourceGroupName $testResourceGroup + $deployedPrivateEndpoints.Count | Should -BeGreaterThan 0 + } + + It 'Private endpoint should have role assignment' { + + $keyVaultResourceId = $DeploymentOutputs.resourceId + $testResourceGroup = ($keyVaultResourceId -split '\/')[4] + $deployedPrivateEndpoints = Get-AzPrivateEndpoint -ResourceGroupName $testResourceGroup + $firstPrivateEndpointResourceId = $deployedPrivateEndpoints[0].Id + $firstPrivateEndpointName = ($firstPrivateEndpointResourceId -split '\/')[-1] + + $roleAssignments = Get-AzRoleAssignment -ResourceName $firstPrivateEndpointName -ResourceType 'Microsoft.Network/privateEndpoints' -ResourceGroupName $testResourceGroup + $roleAssignments | Should -BeGreaterThan 0 + } + } +} \ No newline at end of file From 01f414b81b8839788867b96b0872e072a5763309 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Fri, 16 Feb 2024 22:25:30 +0100 Subject: [PATCH 34/52] Disabled other tests --- .../vault/tests/e2e/defaults/{main.test.bicep => main.test} | 0 .../key-vault/vault/tests/e2e/max/{main.test.bicep => main.test} | 0 .../vault/tests/e2e/waf-aligned/{main.test.bicep => main.test} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename avm/res/key-vault/vault/tests/e2e/defaults/{main.test.bicep => main.test} (100%) rename avm/res/key-vault/vault/tests/e2e/max/{main.test.bicep => main.test} (100%) rename avm/res/key-vault/vault/tests/e2e/waf-aligned/{main.test.bicep => main.test} (100%) diff --git a/avm/res/key-vault/vault/tests/e2e/defaults/main.test.bicep b/avm/res/key-vault/vault/tests/e2e/defaults/main.test similarity index 100% rename from avm/res/key-vault/vault/tests/e2e/defaults/main.test.bicep rename to avm/res/key-vault/vault/tests/e2e/defaults/main.test diff --git a/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep b/avm/res/key-vault/vault/tests/e2e/max/main.test similarity index 100% rename from avm/res/key-vault/vault/tests/e2e/max/main.test.bicep rename to avm/res/key-vault/vault/tests/e2e/max/main.test diff --git a/avm/res/key-vault/vault/tests/e2e/waf-aligned/main.test.bicep b/avm/res/key-vault/vault/tests/e2e/waf-aligned/main.test similarity index 100% rename from avm/res/key-vault/vault/tests/e2e/waf-aligned/main.test.bicep rename to avm/res/key-vault/vault/tests/e2e/waf-aligned/main.test From 64900a11297690b05d148614b2476b460b27dff8 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Fri, 16 Feb 2024 23:20:28 +0100 Subject: [PATCH 35/52] Updated ref --- .../actions/templates/avm-validateModuleDeployment/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/templates/avm-validateModuleDeployment/action.yml b/.github/actions/templates/avm-validateModuleDeployment/action.yml index 23b09ac479..e89f660d82 100644 --- a/.github/actions/templates/avm-validateModuleDeployment/action.yml +++ b/.github/actions/templates/avm-validateModuleDeployment/action.yml @@ -295,7 +295,7 @@ runs: $moduleTestFolderPath = Split-Path $moduleTestFilePath $moduleTestFolderName = Split-Path $moduleTestFolderPath -Leaf - $deploymentOutputs = $env:deploymentOutput | ConvertFrom-Json -AsHashTable + $deploymentOutputs = '${{ steps.deploy_step.outputs.deploymentOutput }}' | ConvertFrom-Json -AsHashTable # --------------------- # # Invoke Pester test(s) # From 2d1e1b74f344468c85b97a3cb9edc2c2a49e145a Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 13:57:46 +0100 Subject: [PATCH 36/52] Update to latest --- .../avm-validateModuleDeployment/action.yml | 3 ++- .../tests/e2e/private-endpoint/topLevel.tests.ps1 | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/actions/templates/avm-validateModuleDeployment/action.yml b/.github/actions/templates/avm-validateModuleDeployment/action.yml index e89f660d82..6fb233b17a 100644 --- a/.github/actions/templates/avm-validateModuleDeployment/action.yml +++ b/.github/actions/templates/avm-validateModuleDeployment/action.yml @@ -315,7 +315,8 @@ runs: } Write-Verbose 'Invoke test with' -Verbose - Write-Verbose ($pesterConfiguration | ConvertTo-Json -Depth 4 | Out-String) -Verbose + Write-Verbose ('Path(s): {0}' -f ($pesterConfiguration.Run.Container | Foreach-Object { ($_.Item.FullName -split '[\\|\/]tests[\\|\/]e2e[\\|\/]')[1] } | Convertto-Json)) -Verbose + Write-Verbose ('Data: {0}' -f ($pesterConfiguration.Run.Container.Data[0] | ConvertTo-Json)) -Verbose $testResults = Invoke-Pester -Configuration $pesterConfiguration diff --git a/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 b/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 index da295343ac..eece91e582 100644 --- a/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 +++ b/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 @@ -14,23 +14,23 @@ param ( [hashtable] $DeploymentOutputs ) +$keyVaultResourceId = $DeploymentOutputs.resourceId +$testResourceGroup = ($keyVaultResourceId -split '\/')[4] +$deployedPrivateEndpoints = Get-AzPrivateEndpoint -ResourceGroupName $testResourceGroup + Describe 'Validate private endpoint deployment' { Context 'Validate sucessful deployment' { - It 'Private endpoints should be deployed' { - $keyVaultResourceId = $DeploymentOutputs.resourceId - $testResourceGroup = ($keyVaultResourceId -split '\/')[4] - $deployedPrivateEndpoints = Get-AzPrivateEndpoint -ResourceGroupName $testResourceGroup + + It "Private endpoints should be deployed in resource group [$testResourceGroup]" { + $deployedPrivateEndpoints.Count | Should -BeGreaterThan 0 } It 'Private endpoint should have role assignment' { - $keyVaultResourceId = $DeploymentOutputs.resourceId - $testResourceGroup = ($keyVaultResourceId -split '\/')[4] - $deployedPrivateEndpoints = Get-AzPrivateEndpoint -ResourceGroupName $testResourceGroup $firstPrivateEndpointResourceId = $deployedPrivateEndpoints[0].Id $firstPrivateEndpointName = ($firstPrivateEndpointResourceId -split '\/')[-1] From 4345ba6770adfa023e3eb6a95c2db58812f65b3b Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 15:17:46 +0100 Subject: [PATCH 37/52] Update to latest --- .../tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 | 2 +- .../vault/tests/e2e/private-endpoint/topLevel.tests.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 b/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 index 4c93e2070d..b29cac28f7 100644 --- a/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 +++ b/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 @@ -15,7 +15,7 @@ Describe 'Validate key vault' { It 'Public endpoint disabled' { - $keyVaultResourceId = $DeploymentOutputs.resourceId + $keyVaultResourceId = $DeploymentOutputs.resourceId.Value $deployedResource = Get-AzResource -ResourceId $keyVaultResourceId diff --git a/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 b/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 index eece91e582..6c1da838df 100644 --- a/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 +++ b/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 @@ -14,7 +14,7 @@ param ( [hashtable] $DeploymentOutputs ) -$keyVaultResourceId = $DeploymentOutputs.resourceId +$keyVaultResourceId = $DeploymentOutputs.resourceId.Value $testResourceGroup = ($keyVaultResourceId -split '\/')[4] $deployedPrivateEndpoints = Get-AzPrivateEndpoint -ResourceGroupName $testResourceGroup From 7e70c08b681693e7781902ae473e6a112e1dd7e7 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 17:41:19 +0100 Subject: [PATCH 38/52] Update to latest --- .../templates/avm-validateModuleDeployment/action.yml | 6 ++++-- .../e2e/private-endpoint/tests/nestedLevel.tests.ps1 | 10 +++++----- .../tests/e2e/private-endpoint/topLevel.tests.ps1 | 9 +++------ 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/.github/actions/templates/avm-validateModuleDeployment/action.yml b/.github/actions/templates/avm-validateModuleDeployment/action.yml index 6fb233b17a..5c48a38532 100644 --- a/.github/actions/templates/avm-validateModuleDeployment/action.yml +++ b/.github/actions/templates/avm-validateModuleDeployment/action.yml @@ -304,8 +304,10 @@ runs: $pesterConfiguration = @{ Run = @{ Container = New-PesterContainer -Path $moduleTestFolderPath -Data @{ - DeploymentOutputs = $deploymentOutputs # Passing in in case we want to directly validate data via the deployment's output - ModuleTestFolderPath = $moduleTestFolderPath # Passing in in case we want to access any data in the test folder / files + TestInputData = @{ + DeploymentOutputs = $deploymentOutputs # Passing in in case we want to directly validate data via the deployment's output + ModuleTestFolderPath = $moduleTestFolderPath # Passing in in case we want to access any data in the test folder / files + } } PassThru = $true } diff --git a/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 b/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 index b29cac28f7..4c68a6cd00 100644 --- a/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 +++ b/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 @@ -7,15 +7,15 @@ ########################### param ( - [Parameter(Mandatory)] - [hashtable] $DeploymentOutputs + [Parameter(Mandatory = $false)] + [hashtable] $TestInputData = @{} ) -Describe 'Validate key vault' { +Describe 'Validate Key Vault' { - It 'Public endpoint disabled' { + It 'Public endpoint should be disabled' { - $keyVaultResourceId = $DeploymentOutputs.resourceId.Value + $keyVaultResourceId = $TestInputData.DeploymentOutputs.resourceId.Value $deployedResource = Get-AzResource -ResourceId $keyVaultResourceId diff --git a/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 b/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 index 6c1da838df..5d75b1894a 100644 --- a/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 +++ b/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 @@ -7,14 +7,11 @@ ########################### param ( - [Parameter(Mandatory)] - [string] $ModuleTestFolderPath, - - [Parameter(Mandatory)] - [hashtable] $DeploymentOutputs + [Parameter(Mandatory = $false)] + [hashtable] $TestInputData = @{} ) -$keyVaultResourceId = $DeploymentOutputs.resourceId.Value +$keyVaultResourceId = $TestInputData.DeploymentOutputs.resourceId.Value $testResourceGroup = ($keyVaultResourceId -split '\/')[4] $deployedPrivateEndpoints = Get-AzPrivateEndpoint -ResourceGroupName $testResourceGroup From 96e5539d9e5246a25dd63843c451baa63a308c6c Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 17:43:08 +0100 Subject: [PATCH 39/52] Update to latest --- .../tests/e2e/private-endpoint/topLevel.tests.ps1 | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 b/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 index 5d75b1894a..4e2bc624d0 100644 --- a/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 +++ b/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 @@ -11,23 +11,24 @@ param ( [hashtable] $TestInputData = @{} ) -$keyVaultResourceId = $TestInputData.DeploymentOutputs.resourceId.Value -$testResourceGroup = ($keyVaultResourceId -split '\/')[4] -$deployedPrivateEndpoints = Get-AzPrivateEndpoint -ResourceGroupName $testResourceGroup - Describe 'Validate private endpoint deployment' { Context 'Validate sucessful deployment' { + It "Private endpoints should be deployed in resource group" { - - It "Private endpoints should be deployed in resource group [$testResourceGroup]" { - + $keyVaultResourceId = $TestInputData.DeploymentOutputs.resourceId.Value + $testResourceGroup = ($keyVaultResourceId -split '\/')[4] + $deployedPrivateEndpoints = Get-AzPrivateEndpoint -ResourceGroupName $testResourceGroup $deployedPrivateEndpoints.Count | Should -BeGreaterThan 0 } It 'Private endpoint should have role assignment' { + $keyVaultResourceId = $TestInputData.DeploymentOutputs.resourceId.Value + $testResourceGroup = ($keyVaultResourceId -split '\/')[4] + $deployedPrivateEndpoints = Get-AzPrivateEndpoint -ResourceGroupName $testResourceGroup + $firstPrivateEndpointResourceId = $deployedPrivateEndpoints[0].Id $firstPrivateEndpointName = ($firstPrivateEndpointResourceId -split '\/')[-1] From 37aad84a74fd57dc4745ec1e3e61ed1a6d91d2f5 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 20:07:43 +0100 Subject: [PATCH 40/52] Small fix --- .../vault/tests/e2e/private-endpoint/topLevel.tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 b/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 index 4e2bc624d0..9dd72e16bf 100644 --- a/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 +++ b/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 @@ -33,7 +33,7 @@ Describe 'Validate private endpoint deployment' { $firstPrivateEndpointName = ($firstPrivateEndpointResourceId -split '\/')[-1] $roleAssignments = Get-AzRoleAssignment -ResourceName $firstPrivateEndpointName -ResourceType 'Microsoft.Network/privateEndpoints' -ResourceGroupName $testResourceGroup - $roleAssignments | Should -BeGreaterThan 0 + $roleAssignments.Count | Should -BeGreaterThan 0 } } } \ No newline at end of file From 0b297f79e2e4ca308f887c8b4c789d9e4b741b9e Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 20:11:52 +0100 Subject: [PATCH 41/52] Aded output --- .../staticValidation/compliance/Set-PesterGitHubOutput.ps1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 index 38f43808ee..fcf364ae35 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 @@ -78,6 +78,11 @@ function Set-PesterGitHubOutput { [string] $BranchName ) + # TODO: Remove output again. Just for debugging. + Write-Verbose '#############' + Write-Verbose ('{0}' -f ($PesterTestResults | ConvertTo-Json -Depth 99)) -Verbose + Write-Verbose '#############' + $passedTests = $PesterTestResults.Passed $failedTests = $PesterTestResults.Failed $skippedTests = $PesterTestResults.Skipped @@ -118,7 +123,6 @@ function Set-PesterGitHubOutput { ) if ($failedTests.Count -gt 0) { - Write-Verbose 'Adding failed tests' $fileContent += [System.Collections.ArrayList]@( '| Name | Error | Source |', '| :-- | :-- | :-- |' From dd8b19d6261bbbd69fcf788f5b5e9b36489b4c51 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 20:49:34 +0100 Subject: [PATCH 42/52] Update to latest --- .../staticValidation/compliance/Set-PesterGitHubOutput.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 index fcf364ae35..3faa32c500 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 @@ -80,7 +80,7 @@ function Set-PesterGitHubOutput { # TODO: Remove output again. Just for debugging. Write-Verbose '#############' - Write-Verbose ('{0}' -f ($PesterTestResults | ConvertTo-Json -Depth 99)) -Verbose + Write-Verbose ('{0}' -f ($PesterTestResults | ConvertTo-Json -Depth 5)) -Verbose Write-Verbose '#############' $passedTests = $PesterTestResults.Passed From cfe99c84215cc67fea2acf42c6f170bd2a7db669 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 20:49:39 +0100 Subject: [PATCH 43/52] Update to latest --- .../staticValidation/compliance/Set-PesterGitHubOutput.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 index 3faa32c500..395bb70ed8 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 @@ -80,7 +80,7 @@ function Set-PesterGitHubOutput { # TODO: Remove output again. Just for debugging. Write-Verbose '#############' - Write-Verbose ('{0}' -f ($PesterTestResults | ConvertTo-Json -Depth 5)) -Verbose + Write-Verbose ('{0}' -f ($PesterTestResults | ConvertTo-Json -Depth 5 -Compress)) -Verbose Write-Verbose '#############' $passedTests = $PesterTestResults.Passed From b849bc855aea9bada94d9205ad5e7a4033f3c57a Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 21:17:15 +0100 Subject: [PATCH 44/52] Update to latest --- .../staticValidation/compliance/Set-PesterGitHubOutput.ps1 | 5 ----- 1 file changed, 5 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 index 395bb70ed8..9687af2fc3 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 @@ -78,11 +78,6 @@ function Set-PesterGitHubOutput { [string] $BranchName ) - # TODO: Remove output again. Just for debugging. - Write-Verbose '#############' - Write-Verbose ('{0}' -f ($PesterTestResults | ConvertTo-Json -Depth 5 -Compress)) -Verbose - Write-Verbose '#############' - $passedTests = $PesterTestResults.Passed $failedTests = $PesterTestResults.Failed $skippedTests = $PesterTestResults.Skipped From 8f2e826bfa373b93b6b8eb1f9008e8deeeb1db2f Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 21:18:01 +0100 Subject: [PATCH 45/52] Enabled additional deploy test --- .../vault/tests/e2e/defaults/{main.test => main.test.bicep} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename avm/res/key-vault/vault/tests/e2e/defaults/{main.test => main.test.bicep} (100%) diff --git a/avm/res/key-vault/vault/tests/e2e/defaults/main.test b/avm/res/key-vault/vault/tests/e2e/defaults/main.test.bicep similarity index 100% rename from avm/res/key-vault/vault/tests/e2e/defaults/main.test rename to avm/res/key-vault/vault/tests/e2e/defaults/main.test.bicep From 420a40a06ba39084021a7ba8cb3f6090be21b8d1 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 21:21:42 +0100 Subject: [PATCH 46/52] Added job conditions --- .../avm-validateModuleDeployment/action.yml | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/.github/actions/templates/avm-validateModuleDeployment/action.yml b/.github/actions/templates/avm-validateModuleDeployment/action.yml index 5c48a38532..61c5b2edb4 100644 --- a/.github/actions/templates/avm-validateModuleDeployment/action.yml +++ b/.github/actions/templates/avm-validateModuleDeployment/action.yml @@ -317,31 +317,35 @@ runs: } Write-Verbose 'Invoke test with' -Verbose - Write-Verbose ('Path(s): {0}' -f ($pesterConfiguration.Run.Container | Foreach-Object { ($_.Item.FullName -split '[\\|\/]tests[\\|\/]e2e[\\|\/]')[1] } | Convertto-Json)) -Verbose + $foundTestPaths = $pesterConfiguration.Run.Container | Foreach-Object { ($_.Item.FullName -split '[\\|\/]tests[\\|\/]e2e[\\|\/]')[1] } + Write-Verbose ('Path(s): {0}' -f ($foundTestPaths | Convertto-Json)) -Verbose Write-Verbose ('Data: {0}' -f ($pesterConfiguration.Run.Container.Data[0] | ConvertTo-Json)) -Verbose - $testResults = Invoke-Pester -Configuration $pesterConfiguration + if($foundTestPaths.Count -gt 0) { + $testResults = Invoke-Pester -Configuration $pesterConfiguration - # ----------------------------------------- # - # Create formatted Pester Test Results File # - # ----------------------------------------- # + # ----------------------------------------- # + # Create formatted Pester Test Results File # + # ----------------------------------------- # - $functionInput = @{ - PesterTestResults = $testResults - OutputFilePath = Join-Path $env:GITHUB_WORKSPACE 'avm' "$moduleTestFolderName-Pester-output.md" - GitHubRepository = $env:GITHUB_REPOSITORY - BranchName = $env:GITHUB_REF - } - - Write-Verbose 'Invoke Pester formatting function with' -Verbose - Write-Verbose ($functionInput | ConvertTo-Json -Depth 0 | Out-String) -Verbose + $functionInput = @{ + PesterTestResults = $testResults + OutputFilePath = Join-Path $env:GITHUB_WORKSPACE 'avm' "$moduleTestFolderName-Pester-output.md" + GitHubRepository = $env:GITHUB_REPOSITORY + BranchName = $env:GITHUB_REF + } - Set-PesterGitHubOutput @functionInput -Verbose + Write-Verbose 'Invoke Pester formatting function with' -Verbose + Write-Verbose ($functionInput | ConvertTo-Json -Depth 0 | Out-String) -Verbose - Write-Output ('{0}={1}' -f 'formattedPesterResultsPath', $functionInput.outputFilePath) >> $env:GITHUB_OUTPUT + Set-PesterGitHubOutput @functionInput -Verbose + Write-Output ('{0}={1}' -f 'formattedPesterResultsPath', $functionInput.outputFilePath) >> $env:GITHUB_OUTPUT + } else { + Write-Output ('{0}={1}' -f 'formattedPesterResultsPath', '') >> $env:GITHUB_OUTPUT + } - name: "Output to GitHub job summaries" - if: always() + if: steps.pester_run_step.outputs.formattedPesterResultsPath != '' shell: pwsh run: | # Grouping task logs From fcf2c98ae1500d054adce211c23b04bf42da6e42 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 23:08:02 +0100 Subject: [PATCH 47/52] Update to latest --- .../templates/avm-validateModuleDeployment/action.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/actions/templates/avm-validateModuleDeployment/action.yml b/.github/actions/templates/avm-validateModuleDeployment/action.yml index 61c5b2edb4..56ffa387a7 100644 --- a/.github/actions/templates/avm-validateModuleDeployment/action.yml +++ b/.github/actions/templates/avm-validateModuleDeployment/action.yml @@ -317,11 +317,12 @@ runs: } Write-Verbose 'Invoke test with' -Verbose - $foundTestPaths = $pesterConfiguration.Run.Container | Foreach-Object { ($_.Item.FullName -split '[\\|\/]tests[\\|\/]e2e[\\|\/]')[1] } - Write-Verbose ('Path(s): {0}' -f ($foundTestPaths | Convertto-Json)) -Verbose - Write-Verbose ('Data: {0}' -f ($pesterConfiguration.Run.Container.Data[0] | ConvertTo-Json)) -Verbose + $foundTestPaths = $pesterConfiguration.Run.Container | Where-Object { -not [String]::IsNullOrEmpty($_.Item.FullName) } | Foreach-Object { ($_.Item.FullName -split '[\\|\/]tests[\\|\/]e2e[\\|\/]')[1] } if($foundTestPaths.Count -gt 0) { + Write-Verbose ('Path(s): {0}' -f ($foundTestPaths | Convertto-Json)) -Verbose + Write-Verbose ('Data: {0}' -f ($pesterConfiguration.Run.Container.Data[0] | ConvertTo-Json)) -Verbose + $testResults = Invoke-Pester -Configuration $pesterConfiguration # ----------------------------------------- # @@ -342,6 +343,7 @@ runs: Write-Output ('{0}={1}' -f 'formattedPesterResultsPath', $functionInput.outputFilePath) >> $env:GITHUB_OUTPUT } else { + Write-Verbose 'Found no Pester test files (*.test.ps1) in test folder' -Verbose Write-Output ('{0}={1}' -f 'formattedPesterResultsPath', '') >> $env:GITHUB_OUTPUT } - name: "Output to GitHub job summaries" From 7d8a44c2346051d066641cc1eadc874fb0e346a5 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 23:18:20 +0100 Subject: [PATCH 48/52] Update to latest --- .../key-vault/vault/tests/e2e/max/{main.test => main.test.bicep} | 0 .../vault/tests/e2e/waf-aligned/{main.test => main.test.bicep} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename avm/res/key-vault/vault/tests/e2e/max/{main.test => main.test.bicep} (100%) rename avm/res/key-vault/vault/tests/e2e/waf-aligned/{main.test => main.test.bicep} (100%) diff --git a/avm/res/key-vault/vault/tests/e2e/max/main.test b/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep similarity index 100% rename from avm/res/key-vault/vault/tests/e2e/max/main.test rename to avm/res/key-vault/vault/tests/e2e/max/main.test.bicep diff --git a/avm/res/key-vault/vault/tests/e2e/waf-aligned/main.test b/avm/res/key-vault/vault/tests/e2e/waf-aligned/main.test.bicep similarity index 100% rename from avm/res/key-vault/vault/tests/e2e/waf-aligned/main.test rename to avm/res/key-vault/vault/tests/e2e/waf-aligned/main.test.bicep From 9de254a1d2c26279f574fdd939e5b4120911c754 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Sat, 17 Feb 2024 23:24:44 +0100 Subject: [PATCH 49/52] Update to latest --- .../actions/templates/avm-validateModuleDeployment/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/templates/avm-validateModuleDeployment/action.yml b/.github/actions/templates/avm-validateModuleDeployment/action.yml index 56ffa387a7..d14a893926 100644 --- a/.github/actions/templates/avm-validateModuleDeployment/action.yml +++ b/.github/actions/templates/avm-validateModuleDeployment/action.yml @@ -321,7 +321,7 @@ runs: if($foundTestPaths.Count -gt 0) { Write-Verbose ('Path(s): {0}' -f ($foundTestPaths | Convertto-Json)) -Verbose - Write-Verbose ('Data: {0}' -f ($pesterConfiguration.Run.Container.Data[0] | ConvertTo-Json)) -Verbose + Write-Verbose ('Data: {0}' -f ($pesterConfiguration.Run.Container.Data[0] | ConvertTo-Json -Depth 3)) -Verbose $testResults = Invoke-Pester -Configuration $pesterConfiguration From 515baba29615ede7d136b00a31c4708bbad527a7 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Mon, 4 Mar 2024 19:16:36 +0100 Subject: [PATCH 50/52] Update to latest --- .../{topLevel.tests.ps1 => tests/connectivity.tests.ps1} | 0 .../tests/{nestedLevel.tests.ps1 => resource.tests.ps1} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename avm/res/key-vault/vault/tests/e2e/private-endpoint/{topLevel.tests.ps1 => tests/connectivity.tests.ps1} (100%) rename avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/{nestedLevel.tests.ps1 => resource.tests.ps1} (100%) diff --git a/avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 b/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/connectivity.tests.ps1 similarity index 100% rename from avm/res/key-vault/vault/tests/e2e/private-endpoint/topLevel.tests.ps1 rename to avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/connectivity.tests.ps1 diff --git a/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 b/avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/resource.tests.ps1 similarity index 100% rename from avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/nestedLevel.tests.ps1 rename to avm/res/key-vault/vault/tests/e2e/private-endpoint/tests/resource.tests.ps1 From 7fcdff44ddd1123264516a7e6e5598997be24b1f Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Mon, 4 Mar 2024 19:38:16 +0100 Subject: [PATCH 51/52] Updated title --- .../templates/avm-validateModuleDeployment/action.yml | 1 + .../compliance/Set-PesterGitHubOutput.ps1 | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/actions/templates/avm-validateModuleDeployment/action.yml b/.github/actions/templates/avm-validateModuleDeployment/action.yml index 265182e4ca..32551cfcf0 100644 --- a/.github/actions/templates/avm-validateModuleDeployment/action.yml +++ b/.github/actions/templates/avm-validateModuleDeployment/action.yml @@ -334,6 +334,7 @@ runs: OutputFilePath = Join-Path $env:GITHUB_WORKSPACE 'avm' "$moduleTestFolderName-Pester-output.md" GitHubRepository = $env:GITHUB_REPOSITORY BranchName = $env:GITHUB_REF + Title = 'Post-deployment test validation summary' } Write-Verbose 'Invoke Pester formatting function with' -Verbose diff --git a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 index 9687af2fc3..897a0b773d 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/Set-PesterGitHubOutput.ps1 @@ -51,6 +51,9 @@ For example: 'Azure/ResourceModules' Optional. The branch the pipeline was triggered from. If provided it will be used to generate a URL to the exact line of the test. For example: 'users/carml/testBranch' +.PARAMETER Title +Optional. The title / header the exported markdown should have. For example: 'Post-deployment test validation summary' + .EXAMPLE Set-PesterGitHubOutput -PesterTestResults @{...} @@ -75,7 +78,10 @@ function Set-PesterGitHubOutput { [string] $GitHubRepository, [Parameter(Mandatory = $false)] - [string] $BranchName + [string] $BranchName, + + [Parameter(Mandatory = $false)] + [string] $Title = 'Pester validation summary' ) $passedTests = $PesterTestResults.Passed @@ -94,7 +100,7 @@ function Set-PesterGitHubOutput { # Header $fileContent = [System.Collections.ArrayList]@( - '# Pester validation summary ', + "# $Title ", '' ) From 1eceb4bb9bceb1dc1870c33fb724bad97195e7c8 Mon Sep 17 00:00:00 2001 From: AlexanderSehr Date: Mon, 4 Mar 2024 19:38:48 +0100 Subject: [PATCH 52/52] Update to latest --- .../actions/templates/avm-validateModuleDeployment/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/templates/avm-validateModuleDeployment/action.yml b/.github/actions/templates/avm-validateModuleDeployment/action.yml index 32551cfcf0..da0c9e3923 100644 --- a/.github/actions/templates/avm-validateModuleDeployment/action.yml +++ b/.github/actions/templates/avm-validateModuleDeployment/action.yml @@ -334,7 +334,7 @@ runs: OutputFilePath = Join-Path $env:GITHUB_WORKSPACE 'avm' "$moduleTestFolderName-Pester-output.md" GitHubRepository = $env:GITHUB_REPOSITORY BranchName = $env:GITHUB_REF - Title = 'Post-deployment test validation summary' + Title = 'Pester post-deployment validation summary' } Write-Verbose 'Invoke Pester formatting function with' -Verbose