updating formatting configuration (#349)

* formatting documents based on the editor configuration, and relaxing max-length linter rules

* formatting documents based on the editor configuration

* formatting documents

* bumping resource providers to latest releases

* formatting document

* fixing linter issues

* formatting documents
This commit is contained in:
Engin Polat 2023-09-22 15:40:20 -07:00 коммит произвёл GitHub
Родитель 42d674cb36
Коммит a57787f2ad
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
18 изменённых файлов: 176 добавлений и 232 удалений

Просмотреть файл

@ -13,7 +13,14 @@
"ghcr.io/eitsupi/devcontainer-features/jq-likes:2.0.0": {},
"ghcr.io/rchaganti/vsc-devcontainer-features/azurebicep:1": {},
"ghcr.io/natescherer/devcontainers-custom-features/powershell-resources:1": {
"resources": ["Az", "Az.App", "Az.Portal", "Az.Search", "Pester", "platyps"]
"resources": [
"Az",
"Az.App",
"Az.Portal",
"Az.Search",
"Pester",
"platyps"
]
},
"ghcr.io/devcontainers/features/node:1": {}
},

Просмотреть файл

@ -16,14 +16,12 @@ jobs:
- uses: actions/checkout@v2
- name: Retrieve Version and Create Version Tag
id: versiontag
# I don't know why, but the first sed command adds a space to the beginning of the string so the second sed
# command removes that space.
# I don't know why, but the first sed command adds a space to the beginning of the string so the second sedcommand removes that space.
# This will create a version tag with a leading "v" followed by the ModuleVersion value inside the quotes
# e.g., "v0.1" for ModuleVersion = "0.1"
run: |
cd ./Modules/BenchPress.Azure
version=v$(sed -n 's/ModuleVersion = "\([^"]*\)"/\1/p' ./BenchPress.Azure.psd1 \
| sed -n 's/\s*//p')
version=v$(sed -n 's/ModuleVersion = "\([^"]*\)"/\1/p' ./BenchPress.Azure.psd1 | sed -n 's/\s*//p')
git tag "$version"
git push origin "$version"
echo "version=$version" >> "$GITHUB_OUTPUT"

3
.github/workflows/ci-module-versioning.yml поставляемый
Просмотреть файл

@ -47,8 +47,7 @@ jobs:
fi
- name: Update manifest file
run: |
sed -i 's/ModuleVersion = "[^"]*"/ModuleVersion = "${{ needs.get-tags.outputs.Version }}"/' \
./Modules/BenchPress.Azure/BenchPress.Azure.psd1
sed -i 's/ModuleVersion = "[^"]*"/ModuleVersion = "${{ needs.get-tags.outputs.Version }}"/' ./Modules/BenchPress.Azure/BenchPress.Azure.psd1
- name: Commit changes to version branch
run: |
if [ "$(git diff --exit-code ./Modules/BenchPress.Azure/BenchPress.Azure.psd1 | wc -l)" -gt 0 ]

3
.github/workflows/ci.yml поставляемый
Просмотреть файл

@ -44,8 +44,7 @@ jobs:
shell: pwsh
run: |
$path = New-Item -Path ./packages -ItemType Directory
Register-PSRepository -Name LocalFeedPSRepo -SourceLocation $path.ToString() `
-PublishLocation $path.ToString() -InstallationPolicy Trusted
Register-PSRepository -Name LocalFeedPSRepo -SourceLocation $path.ToString() -PublishLocation $path.ToString() -InstallationPolicy Trusted
- name: Download module artifacts
uses: actions/download-artifact@v3
with:

5
.github/workflows/pr-mega-linter.yml поставляемый
Просмотреть файл

@ -1,6 +1,4 @@
---
# MegaLinter GitHub Action configuration file
# More info at https://megalinter.io
name: pr-mega-linter
on: # yamllint disable-line rule:truthy
@ -16,13 +14,11 @@ jobs:
name: MegaLinter
runs-on: ubuntu-latest
steps:
# Git Checkout
- name: Checkout Code
uses: actions/checkout@v3
with:
token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
# MegaLinter
- name: MegaLinter
id: ml
uses: oxsecurity/megalinter/flavors/dotnet@v6
@ -30,7 +26,6 @@ jobs:
VALIDATE_ALL_CODEBASE: true
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Upload MegaLinter artifacts
- name: Archive production artifacts
if: ${{ success() }} || ${{ failure() }}
uses: actions/upload-artifact@v3

Просмотреть файл

@ -12,8 +12,7 @@ There are two methods to getting a development environment up and running: local
### Local Setup
Using a local setup either VS Code or Visual Studio can be used to develop code for the BenchPress project. VS Code is
the recommended IDE, but Visual Studio will work as well. For this guide we will cover VS Code prerequisites:
Using a local setup either VS Code or Visual Studio can be used to develop code for the BenchPress project. VS Code is the recommended IDE, but Visual Studio will work as well. For this guide we will cover VS Code prerequisites:
1. Install PowerShell Modules:
- Azure PowerShell Module:
@ -97,13 +96,13 @@ examples/{Resource Type Name}
- Create a new module with the required files mentioned above.
- Add a `Confirm-{Resource Type Name}` function to the [Modules/BenchPress.Azure/BenchPress.Azure.psd1](../Modules/BenchPress.Azure/BenchPress.Azure.psd1) file in alphabetical order.
- Add a `Confirm-{Resource Type Name}` function to the [Modules/BenchPress.Azure/BenchPress.Azure.psd1](./Modules/BenchPress.Azure/BenchPress.Azure.psd1) file in alphabetical order.
- Add `{Resource Type Name}` to the [Modules/BenchPress.Azure/Classes/ResourceType.psm1](../Modules/BenchPress.Azure/Classes/ResourceType.psm1) file in alphabetical order.
- Add `{Resource Type Name}` to the [Modules/BenchPress.Azure/Classes/ResourceType.psm1](./Modules/BenchPress.Azure/Classes/ResourceType.psm1) file in alphabetical order.
- Add `. $PSScriptRoot/Confirm-{Resource Type Name}.ps1` to the beginning of the [Modules/BenchPress.Azure/Public/Get-ResourceByType.ps1](../Modules/BenchPress.Azure/Public/Get-ResourceByType.ps1) file in alphabetical order.
- Add `. $PSScriptRoot/Confirm-{Resource Type Name}.ps1` to the beginning of the [Modules/BenchPress.Azure/Public/Get-ResourceByType.ps1](./Modules/BenchPress.Azure/Public/Get-ResourceByType.ps1) file in alphabetical order.
- Add a section for the new resource type to the end of the [Modules/BenchPress.Azure/Public/Get-ResourceByType.ps1](../Modules/BenchPress.Azure/Public/Get-ResourceByType.ps1) file in alphabetical order, such as;
- Add a section for the new resource type to the end of the [Modules/BenchPress.Azure/Public/Get-ResourceByType.ps1](./Modules/BenchPress.Azure/Public/Get-ResourceByType.ps1) file in alphabetical order, such as;
```powershell
"{Resource Type Name}" {
@ -119,7 +118,7 @@ examples/{Resource Type Name}
.\build.ps1 -Import
```
> Other commands available in the [build.ps1](../build.ps1) can be found in the [Installation.md#Install the BenchPress Module from the Local File System](./docs/installation.md#install-the-benchpress-module-from-the-local-file-system) section
> Other commands available in the [build.ps1](./build.ps1) can be found in the [Installation.md#Install the BenchPress Module from the Local File System](./docs/installation.md#install-the-benchpress-module-from-the-local-file-system) section
- Follow the [Authenticating to Azure](./docs/getting_started.md#authenticating-to-azure) section to authenticate to Azure.
@ -135,13 +134,13 @@ If the resource type is not in the _Core Azure PowerShell module_ (`Az`), you ha
- Find the module that contains the resource type. For example, `Az.Portal` module contains the `Azure Dashboard` resource type.
- Add the module installer to [ci.yml](../.github/workflows/ci.yml) file.
- Add the module installer to [ci.yml](./.github/workflows/ci.yml) file.
```yml
Install-Module -Name Az.{ModuleName} -Scope CurrentUser -Repository PSGallery -Force
```
- Add the module installer to [pr-powershell.yml](../.github/workflows/pr-powershell.yml) file too.
- Add the module installer to [pr-powershell.yml](./.github/workflows/pr-powershell.yml) file too.
```yml
Install-Module Az.{ModuleName} -ErrorAction Stop
@ -165,8 +164,7 @@ Import-Module Az.{ModuleName}
going to file already exists.
1. If your issue exists (all inputs and relevant information is identical to an existing issue):
1. Make relevant comments to add context that helps broaden understanding or helps identify the root concern.
1. Add a [reaction](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) to upvote
(:+1:) or downvote (:-1:) an issue.
1. Add a [reaction](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) to upvote (:+1:) or downvote (:-1:) an issue.
1. If the issue does not exist create a new issue with the following guidelines:
- Do not submit multiple problems or features in a single submitted issue.
- Provide as much information as possible. The more information provided, the more likely that someone will be successful in reproducing the issue and identifying the cause. Provide as much of the following information as possible (not an exhaustive list):
@ -186,8 +184,7 @@ Once an issue has been created or identified to contribute to, the following ste
1. Clone or fork the repository. Clone if you have permissions, fork if you do not.
1. Ensure the latest code is available locally by executing `git fetch all`.
1. Create and checkout a feature branch using the number of the issue in a `feature\<issue #>` branch. For example:
`git checkout -b feature\123`.
1. Create and checkout a feature branch using the number of the issue in a `feature\<issue #>` branch. For example: `git checkout -b feature\123`.
1. Make the changes necessary to address the issue.
1. Commit the final changes to the feature branch using `git commit`
1. Push change to the fork or clone.
@ -243,14 +240,20 @@ Please review and adhere to the tenents of the [Code of Conduct](CODE_OF_CONDUCT
## Contributor License Agreement
To speed up the acceptance of any contribution to the BenchPress repository,
you should sign the Microsoft [Contributor License Agreement (CLA)](https://cla.microsoft.com/) ahead of time.
To speed up the acceptance of any contribution to the BenchPress repository, you should sign the Microsoft [Contributor License Agreement (CLA)](https://cla.microsoft.com/) ahead of time.
If you've already contributed to BenchPress or Microsoft repositories in the past, congratulations!
You've already completed this step.
This a one-time requirement for the BenchPress project.
Signing the CLA process is simple and can be done in less than a minute.
You don't have to do this up-front.
Signing the CLA process is simple and can be done in less than a minute. You don't have to do this up-front.
You can simply clone, fork, and submit your pull request as usual.
When your pull request is created, it is checked by the CLA bot.
If you have signed the CLA, the status check will be set to `passing`. Otherwise, it will stay at `pending`.
Once you sign a CLA, all your existing and future pull requests will have the status check automatically set at `passing`.

Просмотреть файл

@ -2,15 +2,15 @@
# Generated by: CSEDevOps
# Generated on: 12/1/2022
@{
RootModule = "BenchPress.Azure.psm1"
ModuleVersion = "0.2.2"
GUID = "3db0c6b2-7453-4972-a9de-402be1277ac9"
Author = "CSEDevOps"
CompanyName = "Microsoft"
Copyright = "(c) Microsoft. All rights reserved."
Description = "Benchpress Test Framework for Azure Deployment Scenarios"
NestedModules = @()
FunctionsToExport = @(
RootModule = "BenchPress.Azure.psm1"
ModuleVersion = "0.2.2"
GUID = "3db0c6b2-7453-4972-a9de-402be1277ac9"
Author = "CSEDevOps"
CompanyName = "Microsoft"
Copyright = "(c) Microsoft. All rights reserved."
Description = "Benchpress Test Framework for Azure Deployment Scenarios"
NestedModules = @()
FunctionsToExport = @(
"Confirm-Account",
"Confirm-ActionGroup",
"Confirm-AksCluster",
@ -74,17 +74,17 @@
"ShouldBeInLocation",
"ShouldBeInResourceGroup"
)
PrivateData = @{
PrivateData = @{
PSData = @{
Tags = @("Azure", "BenchPress", "Bicep", "ARM", "Test", "ActionGroup", "AKS", "AksCluster", "ContainerRegistry", "KeyVault", "ResourceGroup", "ServicePlan", "SqlDatabase", "SqlServer", "StorageAccount", "VirtualMachine", "WebApp")
LicenseUri = ""
ProjectUri = "https://github.com/Azure/benchpress/"
IconUri = ""
ReleaseNotes = ""
Prerelease = ""
Tags = @("Azure", "BenchPress", "Bicep", "ARM", "Test", "ActionGroup", "AKS", "AksCluster", "ContainerRegistry", "KeyVault", "ResourceGroup", "ServicePlan", "SqlDatabase", "SqlServer", "StorageAccount", "VirtualMachine", "WebApp")
LicenseUri = ""
ProjectUri = "https://github.com/Azure/benchpress/"
IconUri = ""
ReleaseNotes = ""
Prerelease = ""
RequireLicenseAcceptance = $false
}
}
HelpInfoURI = "https://github.com/Azure/benchpress/"
HelpInfoURI = "https://github.com/Azure/benchpress/"
DefaultCommandPrefix = "AzBP"
}

Просмотреть файл

@ -10,12 +10,10 @@ Import-Module Az
function Connect-Account {
<#
.SYNOPSIS
Connect-Account uses environment variable values to log into an Azure context. This is an internal function and
should not be used outside of the BenchPress module.
Connect-Account uses environment variable values to log into an Azure context. This is an internal function and should not be used outside of the BenchPress module.
.DESCRIPTION
Connect-Account is designed to login to an Azure context using environment variables to login as a
ServicePrincipal for the PowerShell session.
Connect-Account is designed to login to an Azure context using environment variables to login as a ServicePrincipal for the PowerShell session.
The expected environment variables are:
AZ_USE_MANAGED_IDENTITY - If set to "true", BenchPress will login to Azure using a Managed Identity
@ -23,12 +21,10 @@ function Connect-Account {
The following Environment variables are required if not using Managed Identity.
AZ_APPLICATION_ID - The Service Principal ID
AZ_ENCRYPTED_PASSWORD - The Service Principal account password properly encrypted using ConvertTo-SecureString
and saved as an environment variable using ConvertFrom-SecureString
AZ_ENCRYPTED_PASSWORD - The Service Principal account password properly encrypted using ConvertTo-SecureString and saved as an environment variable using ConvertFrom-SecureString
AZ_TENANT_ID - The Tenant ID to login to
If the current context that is logged in to matches the Service Principal, Tenant, and Subscription this function
is a no-op.
If the current context that is logged in to matches the Service Principal, Tenant, and Subscription this function is a no-op.
.EXAMPLE
There is only one way to call Connect-Account:
@ -51,7 +47,7 @@ function Connect-Account {
$currentConnection = Get-AzContext
$results = [AuthenticationResult]::new()
# Login Using Managed Identity
# Login Using Managed Identity
if ($useManagedIdentity) {
$connection = Connect-AzAccount -Identity
$subscriptionName = (Get-AzSubscription -SubscriptionId $subscriptionId).Name
@ -59,16 +55,17 @@ function Connect-Account {
$results.Success = $true
$results.AuthenticationData = [AuthenticationData]::new($connection.Context.Subscription.Id)
} else {
# If the current context matches the subscription, tenant, and service principal, then we're already properly
# logged in.
}
else {
# If the current context matches the subscription, tenant, and service principal, then we're already properly logged in.
$applicationId = Get-EnvironmentVariable AZ_APPLICATION_ID
$tenantId = Get-EnvironmentVariable AZ_TENANT_ID
if (IsCurrentAccountLoggedIn($currentConnection)) {
$results.Success = $true
$results.AuthenticationData = [AuthenticationData]::new(($currentConnection).Subscription.Id)
} else {
}
else {
# The current context is not correct
# Create the credentials and login to the correct account
@ -85,29 +82,26 @@ function Connect-Account {
$results.Success = $true
$results.AuthenticationData = [AuthenticationData]::new($connection.Context.Subscription.Id)
} catch {
}
catch {
$thrownError = $_
$results.Success = $false
Write-Error $thrownError
}
}
}
$results
}
$results
}
End { }
End { }
}
function IsCurrentAccountLoggedIn($currentConnection){
function IsCurrentAccountLoggedIn($currentConnection) {
if ($null -ne $currentConnection `
-and ($currentConnection).Account.Type -eq 'ServicePrincipal' `
-and ($currentConnection).Account.Id -eq $applicationId `
-and ($currentConnection).Tenant.Id -eq $tenantId `
-and ($currentConnection).Subscription.Id -eq $subscriptionId) {
-and ($currentConnection).Account.Type -eq 'ServicePrincipal' `
-and ($currentConnection).Account.Id -eq $applicationId `
-and ($currentConnection).Tenant.Id -eq $tenantId `
-and ($currentConnection).Subscription.Id -eq $subscriptionId) {
return $True
}

Просмотреть файл

@ -5,12 +5,10 @@ Import-Module Az
function Disconnect-Account {
<#
.SYNOPSIS
Disconnect-Account uses environment variable values to disconnect from a specific Azure context. This is an
internal function and should not be used outside of the BenchPress module.
Disconnect-Account uses environment variable values to disconnect from a specific Azure context. This is an internal function and should not be used outside of the BenchPress module.
.DESCRIPTION
Disconnect-Account is designed to automatically log out of the specific Azure context using environment variables
to identify the context to disconnect.
Disconnect-Account is designed to automatically log out of the specific Azure context using environment variables to identify the context to disconnect.
The expected environment variables are:
@ -18,8 +16,7 @@ function Disconnect-Account {
AZ_TENANT_ID - The Tenant ID to login to
AZ_SUBSCRIPTION_ID - The Subscription ID to login to
If the current context does not match the Service Principal, Tenant, or Subscription then this function is a
no-op.
If the current context does not match the Service Principal, Tenant, or Subscription then this function is a no-op.
.EXAMPLE
There is only one way to call Disconnect-Account:
@ -39,15 +36,14 @@ function Disconnect-Account {
$applicationId = Get-EnvironmentVariable AZ_APPLICATION_ID
$tenantId = Get-EnvironmentVariable AZ_TENANT_ID
# If the current context doesn't match the target subscription, tentant, and client, then the testing account is
# not logged in. Do nothing.
# If the current context doesn't match the target subscription, tentant, and client, then the testing account is not logged in. Do nothing.
$currentConnection = Get-AzContext
}
Process {
if ($null -eq $currentConnection `
-or ($currentConnection).Account.Type -ne "ServicePrincipal" `
-or ($currentConnection).Account.Id -ne $applicationId `
-or ($currentConnection).Tenant.Id -ne $tenantId) {
-or ($currentConnection).Account.Type -ne "ServicePrincipal" `
-or ($currentConnection).Account.Id -ne $applicationId `
-or ($currentConnection).Tenant.Id -ne $tenantId) {
return
}

Просмотреть файл

@ -1,14 +1,10 @@
function Get-EnvironmentVariable {
<#
.SYNOPSIS
Get-EnvironmentVariable is a private helper method that retrieves environment variables with the
expectation that by default if they are not present that an error will be thrown.
An override switch -DontThrowIfMissing can provided to skip throwing the exception.
Get-EnvironmentVariable is a private helper method that retrieves environment variables with the expectation that by default if they are not present that an error will be thrown. An override switch -DontThrowIfMissing can provided to skip throwing the exception.
.DESCRIPTION
Get-EnvironmentVariable retrieves the environment variable specified by the input parameter and checks to
be sure that a value is present for that environment variable. If the value is missing or whitespace a error
be be thrown unless the -DontThrowIfMissing switch is provided.
Get-EnvironmentVariable retrieves the environment variable specified by the input parameter and checks to be sure that a value is present for that environment variable. If the value is missing or whitespace a error be be thrown unless the -DontThrowIfMissing switch is provided.
.PARAMETER VariableName
This is the name of the environment variable to retrieve and validate that a value is present.
@ -39,7 +35,7 @@
#>
[OutputType([System.String])]
param (
[Parameter(Mandatory=$true, Position=0)]
[Parameter(Mandatory = $true, Position = 0)]
[string]$VariableName,
[switch]$DontThrowIfMissing
)
@ -61,7 +57,7 @@
function Get-RequiredEnvironmentVariable {
[OutputType([System.String])]
param (
[Parameter(Mandatory=$true, Position=0)]
[Parameter(Mandatory = $true, Position = 0)]
[string]$VariableName
)
Begin {
@ -74,4 +70,3 @@ function Get-RequiredEnvironmentVariable {
$value
}
}

Просмотреть файл

@ -23,16 +23,18 @@
#>
$propertyName = 'Location'
if ($null -eq $ActualValue){
if ($null -eq $ActualValue) {
[bool] $succeeded = $false
$failureMessage = "ConfirmResult is null or empty."
} elseif (-not [bool]$ActualValue.ResourceDetails.PSObject.Properties[$propertyName]) {
}
elseif (-not [bool]$ActualValue.ResourceDetails.PSObject.Properties[$propertyName]) {
[bool] $succeeded = $false
$failureMessage = "Resource does not have a location property. It is null or empty."
} else {
}
else {
# Both expected and actual locations should be normalized with no spaces
$resourceLocation = $ActualValue.ResourceDetails.Location -replace " ",""
$expectedLocation = $ExpectedValue -replace " ",""
$resourceLocation = $ActualValue.ResourceDetails.Location -replace " ", ""
$expectedLocation = $ExpectedValue -replace " ", ""
[bool] $succeeded = $resourceLocation -ieq $expectedLocation
if ($Negate) { $succeeded = -not $succeeded }
@ -40,7 +42,8 @@
if (-not $succeeded) {
if ($Negate) {
$failureMessage = "Resource is deployed, incorrectly, in $resourceLocation."
} else {
}
else {
$failureMessage = "Resource not in location or there was an error when confirming resource.
Expected $ExpectedValue but got $resourceLocation."
if ($Because) { $failureMessage = "Resource not in location $Because." }
@ -49,12 +52,12 @@
}
return [pscustomobject]@{
Succeeded = $succeeded
FailureMessage = $failureMessage
Succeeded = $succeeded
FailureMessage = $failureMessage
}
}
Add-ShouldOperator -Name BeInLocation `
-InternalName 'ShouldBeInLocation' `
-Test ${function:ShouldBeInLocation} `
-Alias 'SBIL'
-InternalName 'ShouldBeInLocation' `
-Test ${function:ShouldBeInLocation} `
-Alias 'SBIL'

Просмотреть файл

@ -25,15 +25,18 @@
$rgNameProperty = 'ResourceGroupName'
$idProperty = 'Id'
if ($null -eq $ActualValue){
if ($null -eq $ActualValue) {
[bool] $succeeded = $false
$failureMessage = "ConfirmResult is null or empty."
} else {
if ([bool]$ActualValue.ResourceDetails.PSObject.Properties[$rgProperty]){
}
else {
if ([bool]$ActualValue.ResourceDetails.PSObject.Properties[$rgProperty]) {
$resourceGroupName = $ActualValue.ResourceDetails.$rgProperty
} elseif ([bool]$ActualValue.ResourceDetails.PSObject.Properties[$rgNameProperty]){
}
elseif ([bool]$ActualValue.ResourceDetails.PSObject.Properties[$rgNameProperty]) {
$resourceGroupName = $ActualValue.ResourceDetails.$rgNameProperty
} elseif ([bool]$ActualValue.ResourceDetails.PSObject.Properties[$idProperty]){
}
elseif ([bool]$ActualValue.ResourceDetails.PSObject.Properties[$idProperty]) {
# If it does not have a property for resource group, then we can maybe get the resource group from Id
# ex: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/'
# providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
@ -49,33 +52,35 @@
}
# Some resources don't have any of the resource group properties
if ($null -eq $resourceGroupName){
if ($null -eq $resourceGroupName) {
[bool] $succeeded = $false
$failureMessage = "Resource does not have a ResourceGroup, a ResourceGroupName, or an Id (with a RG) property.
They are null or empty."
} else {
[bool] $succeeded = $resourceGroupName -eq $ExpectedValue
if ($Negate) { $succeeded = -not $succeeded }
}
else {
[bool] $succeeded = $resourceGroupName -eq $ExpectedValue
if ($Negate) { $succeeded = -not $succeeded }
if (-not $succeeded) {
if ($Negate) {
$failureMessage = "Resource is deployed, incorrectly, in $resourceGroupName."
} else {
$failureMessage = "Resource not in resource group or there was an error when confirming resource.
Expected $ExpectedValue but got $resourceGroupName."
if ($Because) { $failureMessage = "Resource not in resource group. This failed $Because." }
}
if (-not $succeeded) {
if ($Negate) {
$failureMessage = "Resource is deployed, incorrectly, in $resourceGroupName."
}
else {
$failureMessage = "Resource not in resource group or there was an error when confirming resource.
Expected $ExpectedValue but got $resourceGroupName."
if ($Because) { $failureMessage = "Resource not in resource group. This failed $Because." }
}
}
}
}
return [pscustomobject]@{
Succeeded = $succeeded
FailureMessage = $failureMessage
Succeeded = $succeeded
FailureMessage = $failureMessage
}
}
Add-ShouldOperator -Name BeInResourceGroup `
-InternalName 'ShouldBeInResourceGroup' `
-Test ${function:ShouldBeInResourceGroup} `
-Alias 'SBIRG'
-InternalName 'ShouldBeInResourceGroup' `
-Test ${function:ShouldBeInResourceGroup} `
-Alias 'SBIRG'

Просмотреть файл

@ -21,17 +21,19 @@
.OUTPUTS
PSCustomObject
#>
if ($null -eq $ActualValue){
if ($null -eq $ActualValue) {
[bool] $succeeded = $false
$failureMessage = "ConfirmResult is null or empty."
} else {
}
else {
[bool] $succeeded = $ActualValue.Success
if ($Negate) { $succeeded = -not $succeeded }
if (-not $succeeded) {
if ($Negate) {
$failureMessage = "Resource is currently deployed, but should not be."
} else {
}
else {
$failureMessage = "Resource not deployed or there was an error when confirming resource."
if ($Because) { $failureMessage = "Resource not available $Because." }
}
@ -45,6 +47,6 @@
}
Add-ShouldOperator -Name BeSuccessful `
-InternalName 'ShouldBeSuccessful' `
-Test ${function:ShouldBeSuccessful} `
-Alias 'SBS'
-InternalName 'ShouldBeSuccessful' `
-Test ${function:ShouldBeSuccessful} `
-Alias 'SBS'

Просмотреть файл

@ -21,22 +21,16 @@ Please see the following for more info:
## Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit <https://cla.opensource.microsoft.com>.
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit <https://cla.opensource.microsoft.com>.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
trademarks or logos is subject to and must follow
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
Any use of third-party trademarks or logos are subject to those third-party's policies.

Просмотреть файл

@ -1,7 +1,5 @@
BeforeAll {
# Navigate to ../../docs/installation.md to build BenchPress module"
#Import-Module "../../bin/BenchPress.Azure.psd1"
Import-Module "BenchPress.Azure"
$Script:rgName = "benchpress-rg-${env:ENVIRONMENT_SUFFIX}"
$Script:webAppName = "benchpress-web-${env:ENVIRONMENT_SUFFIX}"
@ -107,6 +105,5 @@ Describe 'Web Apps Tests' {
}
AfterAll {
Get-Module Az-InfrastructureTesting | Remove-Module
Get-Module BenchPress.Azure | Remove-Module
Get-Module "BenchPress.Azure" | Remove-Module
}

Просмотреть файл

@ -29,6 +29,7 @@ graph LR
```
The current CI/CD process generally consists of three stages, and each stage handles certain steps.
The three "stages" are:
- Pull Request (PR)
@ -37,37 +38,28 @@ The three "stages" are:
### Pull Request
When any pull requests are opened with a target branch of `main`, they will automatically trigger the PR stage of the
CI/CD process. This stage consists of the following steps:
When any pull requests are opened with a target branch of `main`, they will automatically trigger the PR stage of the CI/CD process. This stage consists of the following steps:
- [`pr-mega-linter.yml`](../.github/workflows/pr-mega-linter.yml) - Running [MegaLinter](https://megalinter.io/latest/)
for code styling and formatting.
- [`pr-dotnet.yml`](../.github/workflows/pr-dotnet.yml) and [`pr-powershell`](../.github/workflows/pr-powershell.yml) -
Unit tests (for .NET Solution and PowerShell code) for code quality and testing.
- [`pr-mega-linter.yml`](../.github/workflows/pr-mega-linter.yml) - Running [MegaLinter](https://megalinter.io/latest/) for code styling and formatting.
- [`pr-dotnet.yml`](../.github/workflows/pr-dotnet.yml) and [`pr-powershell`](../.github/workflows/pr-powershell.yml) - Unit tests (for .NET Solution and PowerShell code) for code quality and testing.
### Continuous Integration
After pull requests are merged to the `main` branch, they will automatically trigger the CI stage of the CI/CD process.
This stage consists of the following steps:
- [`ci.yml`](../.github/workflows/ci.yml) - builds the .NET solution and the final module file for BenchPress. It also
tests the module for deployability to a local PS Repo. Lastly, it generates documentation using help comments for
PowerShell cmdlets and saves documentation to a branch named `docs`. A PR will need to be **manually** created with any
changes pushed to the `docs` branch in order to merge them into `main`.
- The local "PowerShell Gallery" uses the workflow runner's local filesystem to simulate PowerShell Gallery. We then
push and pull from this filesystem using the same PowerShell cmdlets that are used to interact with PowerShell
Gallery.
- [`ci-module-versioning.yml`](../.github/workflows/ci-module-versioning.yml) - calculating the version for the
PowerShell module using GitVersion and writing it to the module manifest on a branch named `version`. A PR will
need to be **manually** created with any changes pushed to the `version` branch in order to merge them into `main`.
- [`ci.yml`](../.github/workflows/ci.yml) - builds the .NET solution and the final module file for BenchPress. It also tests the module for deployability to a local PS Repo. Lastly, it generates documentation using help comments for PowerShell cmdlets and saves documentation to a branch named `docs`. A PR will need to be **manually** created with any changes pushed to the `docs` branch in order to merge them into `main`.
- The local "PowerShell Gallery" uses the workflow runner's local filesystem to simulate PowerShell Gallery. We then push and pull from this filesystem using the same PowerShell cmdlets that are used to interact with PowerShell Gallery.
- [`ci-module-versioning.yml`](../.github/workflows/ci-module-versioning.yml) - calculating the version for the PowerShell module using GitVersion and writing it to the module manifest on a branch named `version`. A PR will need to be **manually** created with any changes pushed to the `version` branch in order to merge them into `main`.
### Continuous Deployment
The final stage of the CI/CD process is the CD stage. This stage is a little unlike the others where some of the steps
are not automatically triggered. This stage consists of the following steps:
The final stage of the CI/CD process is the CD stage. This stage is a little unlike the others where some of the steps are not automatically triggered. This stage consists of the following steps:
- [`cd-psgallery.yml`](../.github/workflows/cd-psgallery.yml) - manually triggered to handle deploying the PowerShell
module to the public PowerShell Gallery.
- [`cd-version-tag-release.yml`](../.github/workflows/cd-version-tag-release.yml) - triggered if a PR was merged from
`version` branch into the `main` branch. It will handle tagging the `main` branch and creating a GitHub release with
that version tag.
- [`cd-psgallery.yml`](../.github/workflows/cd-psgallery.yml) - manually triggered to handle deploying the PowerShell module to the public PowerShell Gallery.
- [`cd-version-tag-release.yml`](../.github/workflows/cd-version-tag-release.yml) - triggered if a PR was merged from `version` branch into the `main` branch. It will handle tagging the `main` branch and creating a GitHub release with that version tag.

Просмотреть файл

@ -4,30 +4,22 @@
The basic usage pattern for writing automated tests with BenchPress is to:
1. Write tests using [Pester testing framework](https://pester.dev/docs/quick-start). Create test files ending in
`Tests.ps1` and run test files using `Invoke-Pester` .
1. Write tests using [Pester testing framework](https://pester.dev/docs/quick-start). Create test files ending in `Tests.ps1` and run test files using `Invoke-Pester`.
1. Deploy resources to Azure using bicep (or helpers from BenchPress).
1. Use BenchPress to return information about deployed resources.
1. (Optional) Use BenchPress to tear down resources at the end of the test.
## Requirements
BenchPress uses PowerShell and the Azure Az PowerShell module. Users should use Pester
as their testing framework and runner. To use BenchPress, have the following installed:
BenchPress uses PowerShell and the Azure Az PowerShell module. Users should use Pester as their testing framework and runner. To use BenchPress, have the following installed:
- [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows)
(PowerShell 7+ recommended)
- [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows) (PowerShell 7+ recommended)
- [Az PowerShell module](https://learn.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-9.3.0)
- [Az.App PowerShell module](https://learn.microsoft.com/en-us/powershell/module/az.app/?view=azps-9.5.0) for any
testing of Container Applications. Az.App is not GA yet which is why it is not included with the main Az
PowerShell module.
- [Az.Portal PowerShell module](https://learn.microsoft.com/en-us/powershell/module/az.app/?view=azps-9.5.0) for any
testing of Azure Dashboards. Az.Portal is not GA yet which is why it is not included with the main Az
PowerShell module.
- [Az.App PowerShell module](https://learn.microsoft.com/en-us/powershell/module/az.app/?view=azps-9.5.0) for any testing of Container Applications. Az.App is not GA yet which is why it is not included with the main Az PowerShell module.
- [Az.Portal PowerShell module](https://learn.microsoft.com/en-us/powershell/module/az.app/?view=azps-9.5.0) for any testing of Azure Dashboards. Az.Portal is not GA yet which is why it is not included with the main Az PowerShell module.
- [Pester](https://pester.dev/docs/introduction/installation)
- [Bicep](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/install#azure-powershell)
- [Service Principal](https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal)
created for your application.
- [Service Principal](https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal) created for your application.
An Azure subscription that you can deploy resources to is also a requirement.
@ -99,9 +91,7 @@ The easiest way to get started with BenchPress is to use the files in the `examp
## Running a test file
1. You can use any of the `*.Tests.ps1` for this quickstart, but we will specifically use `containerRegistry.bicep` and
`ContainerRegistry.Tests.ps1` as our examples. To run the `ContainerRegistry.Tests.ps1` tests, execute
`.\ContainerRegistry.Tests.ps1` or `Invoke-Pester -Path .\ContainerRegistry.Tests.ps1`.
1. You can use any of the `*.Tests.ps1` for this quickstart, but we will specifically use `containerRegistry.bicep` and `ContainerRegistry.Tests.ps1` as our examples. To run the `ContainerRegistry.Tests.ps1` tests, execute `.\ContainerRegistry.Tests.ps1` or `Invoke-Pester -Path .\ContainerRegistry.Tests.ps1`.
1. Your test results will most likely be 5 test failures, all saying something similar to this:
@ -126,8 +116,7 @@ The easiest way to get started with BenchPress is to use the files in the `examp
## Walkthrough of Test File
Let's walkthrough the `ContainerRegistry.Tests.ps1` file to understand how BenchPress is used to test our
Infrastructure as Code (IaC) and why our tests are failing.
Let's walkthrough the `ContainerRegistry.Tests.ps1` file to understand how BenchPress is used to test our Infrastructure as Code (IaC) and why our tests are failing.
```PowerShell
BeforeAll {
@ -204,11 +193,7 @@ AfterAll {
```
This test file uses Pester's `Describe` and `It` keywords to represent tests.
Each test checks different scenarios: Whether a Container Registry exists, if it's in the correct resource group,
and if it has the correct location set. We also import the
BenchPress module in the `BeforeAll` block (which looks different depending on if you're running locally -
see [installation](./installation.md).
This test file uses Pester's `Describe` and `It` keywords to represent tests. Each test checks different scenarios: Whether a Container Registry exists, if it's in the correct resource group, and if it has the correct location set. We also import the BenchPress module in the `BeforeAll` block (which looks different depending on if you're running locally - see [installation](./installation.md)).
The first two `It` blocks are similar:
@ -240,12 +225,7 @@ It "Should contain a Container Registry named $acrName with a Standard SKU - Con
}
```
This test uses the `Confirm-AzBPResource` helper
from BenchPress. `Confirm-AzBPResource` returns a `ConfirmResult` object
with information about the success of the call,
resource details, authentication data and an error record.
Assuming the container registry exists, we assert that
the object returned by `Confirm-AzBPResource` is successful.
This test uses the `Confirm-AzBPResource` helper from BenchPress. `Confirm-AzBPResource` returns a `ConfirmResult` object with information about the success of the call, resource details, authentication data and an error record. Assuming the container registry exists, we assert that the object returned by `Confirm-AzBPResource` is successful.
The second test checks if a specific property key and value exists.
@ -271,8 +251,7 @@ It "Should contain a Container Registry named $acrName in $rgName" {
}
```
The fourth test is a negative test, and interestingly, it's the only test that passes. This is because
the resource defined in the file does not exist yet:
The fourth test is a negative test, and interestingly, it's the only test that passes. This is because the resource defined in the file does not exist yet:
```PowerShell
It "Should not contain a Container Registry named $noContainerRegistryName" {
@ -297,25 +276,19 @@ Take note of the `-ErrorAction SilentlyContinue` comment.
Now that we've done a walkthrough of all tests, let's fix them.
Most of the tests assumed that our container registry was already deployed to a resource group. However, we
never deployed the `containerRegistry.bicep` file ourselves! Most tests also assumed we had an existing resource group
to deploy to, but we never deployed that either! Let's go ahead and fix these assumptions now:
Most of the tests assumed that our container registry was already deployed to a resource group. However, we never deployed the `containerRegistry.bicep` file ourselves! Most tests also assumed we had an existing resource group to deploy to, but we never deployed that either! Let's go ahead and fix these assumptions now:
1. Create a resource group in your subscription.
1. Deploy the container registry bicep file to that resource group:
```PowerShell
New-AzResourceGroupDeployment -ResourceGroupName "<your-resource-group-name>"`
-TemplateFile ".\containerRegistry.bicep"
New-AzResourceGroupDeployment -ResourceGroupName "<your-resource-group-name>" -TemplateFile ".\containerRegistry.bicep"
```
(If you get an error that bicep is not recognized, you may need to
[manually install](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/install#azure-powershell)
bicep.)
(If you get an error that bicep is not recognized, you may need to [manually install](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/install#azure-powershell) bicep.)
1. Update the `ContainerRegistry.Tests.ps1` file to replace the placeholder values with the actual values from your
deployment. Note that when executing `New-AzResourceGroupDeployment` the output will contain the name generated for
the new Container Registry.
1. Update the `ContainerRegistry.Tests.ps1` file to replace the placeholder values with the actual values from your deployment. Note that when executing `New-AzResourceGroupDeployment` the output will contain the name generated for the new Container Registry.
`$Script:rgName = '<your-resource-group-name>'`
`$Script:acrName = '<your-container-registry-name>'`

Просмотреть файл

@ -3,15 +3,14 @@
There are two general ways to install BenchPress:
- Install from the PowerShell Gallery
- Import from a local copy of the BenchPress GitHub repository
## Install From the PowerShell Gallery
In order to install from the PowerShell Gallery follow these steps from a PowerShell terminal:
1. Ensure that the latest version of
[PowerShellGet][1]
is installed.
1. Ensure that the latest version of [PowerShellGet][1] is installed.
1. Execute `Install-Module -Name Az.InfrastructureTesting`
1. To make the module available to the current session execute `Import-Module -Name Az.InfrastructureTesting`
@ -21,8 +20,7 @@ is installed.
### Copy the Repo to the Local File System
A local copy of the git repository must be present by either cloning from the source GitHub repository or forking the
source GitHub repository and cloning that repository locally.
A local copy of the git repository must be present by either cloning from the source GitHub repository or forking the source GitHub repository and cloning that repository locally.
To fork the repository you must have a GitHub account and follow these steps:
@ -33,24 +31,18 @@ To fork the repository you must have a GitHub account and follow these steps:
To clone the repository:
1. From a terminal window navigate to the directory that the cloned repository will be cloned.
1. If cloning from the source repository execute: `git clone https://github.com/Azure/benchpress.git`. This will
automatically create the `benchpress` folder and copy all files to the local file system.
1. If cloning from the source repository execute: `git clone https://github.com/Azure/benchpress.git`. This will automatically create the `benchpress` folder and copy all files to the local file system.
1. If cloning from a forked repository:
1. Navigate to the forked repository's `Code` page in GitHub.
1. Click the `Code` button drop down and under the `HTTPS` tab copy the URL.
1. In the terminal window execute `git clone <copied path>`. As above, this will copy all files to the local file
system.
1. In the terminal window execute `git clone <copied path>`. As above, this will copy all files to the local file system.
### Install the BenchPress Module from the Local File System
Once a local copy of the BenchPress repository exists, to install the BenchPress Module, from the project root path
execute `./build.ps1 -Import`. This will create a `.psm1` file in the `bin` directory that will dot source all cmdlets
in the `Public` and `Private` folders, `Export-ModuleMember` for all `Public` cmdlets, and sets the proper `using`
statements to import classes.
Once a local copy of the BenchPress repository exists, to install the BenchPress Module, from the project root path execute `./build.ps1 -Import`. This will create a `.psm1` file in the `bin` directory that will dot source all cmdlets in the `Public` and `Private` folders, `Export-ModuleMember` for all `Public` cmdlets, and sets the proper `using` statements to import classes.
To clean the `bin` folder before outputting the artifacts from `build.ps1` the `-Clean` flag can be passed.
To test the load time the `-Load` flag can be passed.
To test the build as an inline `.psm1` file pass the `-InLine` flag. This will consolidate all files in the `Classes`
, `Public`, and `Private` folders into a single file instead of dot sourcing the files.
To test the build as an inline `.psm1` file pass the `-InLine` flag. This will consolidate all files in the `Classes`, `Public`, and `Private` folders into a single file instead of dot sourcing the files.