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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -340,4 +340,6 @@ Tests/Scratch.ps1
*TestResults*.xml
Tests/config*.json
!Tests/config.sample.json
Tests/aaTest.ps1
Tests/aaTest.ps1
# Temporary files generated by unit tests
test/**/~*.json
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ The main advantage of the module is the ability to publish all the Azure Data Fa
- [Publish from Azure DevOps](#publish-from-azure-devops)
- [Using Publish Azure Data factory (task)](#using-publish-azure-data-factory-task)
- [Using Azure PowerShell (task)](#using-azure-powershell-task)
- [Running tests locally](#running-tests-locally)
- [Release Notes](#release-notes)
- [Misc](#misc)
- [New feature requests](#new-feature-requests)
Expand Down Expand Up @@ -947,6 +948,8 @@ Cmdlet: `Export-AdfToArmTemplate`
This cmdlet uses [**ADFUtilities** NPM package](https://www.npmjs.com/package/@microsoft/azure-data-factory-utilities) provided by Microsoft.
It does exactly the same actions as you can do with ADF UI by clicking **Validate all** and then **Export ARM Template**.

> **Prerequisite:** [Node.js](https://nodejs.org/) (LTS) with `npm` must be installed and available in `PATH`.

### Parameters:
- `RootFolder` - Source folder where all ADF objects are kept. The folder should contain subfolders like pipeline, linkedservice, etc.
- `SubscriptionId` - Optional.
Expand Down Expand Up @@ -1023,6 +1026,28 @@ steps:
azurePowerShellVersion: LatestVersion```
```

# Running tests locally

### Prerequisites
- [PowerShell 7+](https://learn.microsoft.com/powershell/scripting/install/installing-powershell)
- PowerShell modules: `Pester` (5.3.3 or later), `PSScriptAnalyzer`, `Az.DataFactory`, `Az.Resources`, `Az.Storage`
- [Node.js](https://nodejs.org/) (LTS) with `npm` in `PATH` - required by `Export-AdfToArmTemplate` tests

```powershell
Install-Module Pester -MinimumVersion 5.3.3 -Scope CurrentUser -Force -SkipPublisherCheck
Install-Module PSScriptAnalyzer, Az.DataFactory, Az.Resources, Az.Storage -Scope CurrentUser
winget install OpenJS.NodeJS.LTS
```

Some tests deploy to a real Azure Data Factory, so sign in with `Connect-AzAccount` to a subscription containing the test resource group.

### Run
From the repository root:
```powershell
& '.\test\!RunAllTests.ps1' -folder '.\' -TestFilenameFilter '*' -InstallModules:$false
```
Use `-TestFilenameFilter` to run selected files only (e.g. `'Start-Trigger'`), and `-MajorRelease` to include tests tagged `Integration`.

# Release Notes

New features, bug fixes and changes [can be found here](https://github.com/SQLPlayer/azure.datafactory.tools/blob/master/changelog.md).
Expand Down
2 changes: 1 addition & 1 deletion public/New-AdfPublishOption.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function New-AdfPublishOption {
if (![string]::IsNullOrWhitespace($FilterFilePath)) {
Write-Verbose "Loading rules for selective deployment from file '$FilterFilePath'..."
if ($false -eq (Test-Path -Path $FilterFilePath)) {
Write-Error "ADFT0026: File does not exist: $FilterFilePath"
throw "ADFT0026: File does not exist: $FilterFilePath"
}
$FilterText = Get-Content -Path $FilterFilePath -Encoding "UTF8"
if ($null -eq $FilterText) { $FilterText = '' }
Expand Down
8 changes: 3 additions & 5 deletions test/!RunAllTests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ Write-Host " ========= ENVIRONMENT =========="
Write-Host "Host Name: $($Host.name)"
Write-Host "PowerShell Version: $($PSVersionTable.PSVersion)"

$rootPath = Switch ($Host.name) {
'Visual Studio Code Host' { split-path $psEditor.GetEditorContext().CurrentFile.Path }
'Windows PowerShell ISE Host' { Split-Path -Path $psISE.CurrentFile.FullPath }
'ConsoleHost' { $PSScriptRoot }
}
$rootPath = $PSScriptRoot
$folder = Split-Path $rootPath -Parent
# $MajorRelease = $false
# $TestFilenameFilter = "*"
Expand Down Expand Up @@ -57,6 +53,8 @@ if ($InstallModules) {
} else {
Write-Host "Installation skipped."
}
# Unload legacy Pester (e.g. built-in 3.4.0) so its Should doesn't shadow the newer one
Get-Module Pester | Where-Object Version -lt '5.3.3' | Remove-Module -Force
Import-Module 'Pester' -MinimumVersion 5.3.3
Import-Module 'PSScriptAnalyzer'
Import-Module 'Az.Storage'
Expand Down
6 changes: 3 additions & 3 deletions test/Get-AzDFV2Credential.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,19 @@ InModuleScope azure.datafactory.tools {

It 'Should call Invoke-AzRestMethod once' {
Get-AzDFV2Credential -adfi $script:adfi
Assert-MockCalled Invoke-AzRestMethod -Times 1 -Exactly
Should -Invoke Invoke-AzRestMethod -Times 1 -Exactly
}

It 'Should call Invoke-AzRestMethod with correct credentials URL' {
Get-AzDFV2Credential -adfi $script:adfi
Assert-MockCalled Invoke-AzRestMethod -Times 1 -Exactly -ParameterFilter {
Should -Invoke Invoke-AzRestMethod -Times 1 -Exactly -ParameterFilter {
$Uri -eq "https://management.azure.com$($script:adfi.DataFactoryId)/credentials?api-version=2018-06-01"
}
}

It 'Should call Invoke-AzRestMethod using GET method' {
Get-AzDFV2Credential -adfi $script:adfi
Assert-MockCalled Invoke-AzRestMethod -Times 1 -Exactly -ParameterFilter {
Should -Invoke Invoke-AzRestMethod -Times 1 -Exactly -ParameterFilter {
$Method -eq 'GET'
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/Integration.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ InModuleScope azure.datafactory.tools {
Stop-Triggers -adf $script:adf
$allTriggers = Get-AzDataFactoryV2Trigger -DataFactoryName "$DataFactoryName" -ResourceGroupName "$ResourceGroupName"
$activeTriggers = $allTriggers | Where-Object { $_.RuntimeState -ne "Stopped" } | ToArray
Assert-MockCalled Stop-AzDataFactoryV2Trigger -Times $activeTriggers.Count
Should -Invoke Stop-AzDataFactoryV2Trigger -Times $activeTriggers.Count
}
}
}
Expand Down
20 changes: 10 additions & 10 deletions test/Publish-AdfV2FromJson-1.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,16 @@ InModuleScope azure.datafactory.tools {
-Location $script:Location -DataFactoryName $script:DataFactoryName -Option $o
}

It 'adf2 Should deploy credential1 to ADF service' {
$script:RootFolder = Join-Path $PSScriptRoot "adf2"
$o = New-AdfPublishOption
$o.StopStartTriggers = $false
$o.Includes.Add("credential.credential1", "")
Publish-AdfV2FromJson -RootFolder $script:RootFolder -ResourceGroupName $script:ResourceGroupName `
-Location $script:Location -DataFactoryName $script:DataFactoryName -Option $o
$adfIns = Get-AdfFromService -FactoryName $script:DataFactoryName -ResourceGroupName $script:ResourceGroupName
$adfIns.Credentials | Where-Object { $_.Name -eq 'credential1' } | Should -Not -BeNullOrEmpty
}
# It 'adf2 Should deploy credential1 to ADF service' {
# $script:RootFolder = Join-Path $PSScriptRoot "adf2"
# $o = New-AdfPublishOption
# $o.StopStartTriggers = $false
# $o.Includes.Add("credential.credential1", "")
# Publish-AdfV2FromJson -RootFolder $script:RootFolder -ResourceGroupName $script:ResourceGroupName `
# -Location $script:Location -DataFactoryName $script:DataFactoryName -Option $o
# $adfIns = Get-AdfFromService -FactoryName $script:DataFactoryName -ResourceGroupName $script:ResourceGroupName
# $adfIns.Credentials | Where-Object { $_.Name -eq 'credential1' } | Should -Not -BeNullOrEmpty
# }

}

Expand Down
4 changes: 2 additions & 2 deletions test/Publish-AdfV2FromJson-2.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ InModuleScope azure.datafactory.tools {
-ResourceGroupName "$ResourceGroupName" `
-DataFactoryName "$DataFactoryName" `
-Location "$Location" -Option $opt
Assert-MockCalled Stop-AzDataFactoryV2Trigger -Times 1
Assert-MockCalled Remove-AzDataFactoryV2Trigger -Times 1
Should -Invoke Stop-AzDataFactoryV2Trigger -Times 1
Should -Invoke Remove-AzDataFactoryV2Trigger -Times 1
}


Expand Down
8 changes: 4 additions & 4 deletions test/Start-Trigger.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ InModuleScope azure.datafactory.tools {
$script:attempts = 2
Mock Start-AzDataFactoryV2Trigger { $attempts--; if ($attempts -eq 0) { Write-Host 'OK' } else { throw 'BadRequest' } }
Start-Trigger -ResourceGroupName 'rg' -DataFactoryName 'adf' -Name 'tr1'
Assert-MockCalled Start-AzDataFactoryV2Trigger -Times 2
Should -Invoke Start-AzDataFactoryV2Trigger -Times 2
}

It 'Should retry max 5 times when failure' {
Mock Start-AzDataFactoryV2Trigger { throw 'BadRequest' }
Start-Trigger -ResourceGroupName 'rg' -DataFactoryName 'adf' -Name 'tr1'
Assert-MockCalled Start-AzDataFactoryV2Trigger -Times 5
Should -Invoke Start-AzDataFactoryV2Trigger -Times 5
}

It 'Should wait for provisioning and retry when trigger cannot be updated during provisioning' {
Expand All @@ -52,8 +52,8 @@ InModuleScope azure.datafactory.tools {

Start-Trigger -ResourceGroupName 'rg' -DataFactoryName 'adf' -Name 'tr1'

Assert-MockCalled Start-AzDataFactoryV2Trigger -Times 2
Assert-MockCalled Get-AzDataFactoryV2Trigger -Times 2
Should -Invoke Start-AzDataFactoryV2Trigger -Times 2
Should -Invoke Get-AzDataFactoryV2Trigger -Times 2
}

}
Expand Down
2 changes: 1 addition & 1 deletion test/Stop-Triggers.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ InModuleScope azure.datafactory.tools {
# Stop-Triggers -adf $adf
# $allTriggers = Get-AzDataFactoryV2Trigger -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName
# $activeTriggers = $allTriggers | Where-Object { $_.RuntimeState -ne "Stopped" } | ToArray
# Assert-MockCalled Stop-AzDataFactoryV2Trigger -Times $activeTriggers.Count
# Should -Invoke Stop-AzDataFactoryV2Trigger -Times $activeTriggers.Count
# }
# }

Expand Down
2 changes: 2 additions & 0 deletions test/Test-AdfCode.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ InModuleScope azure.datafactory.tools {
param($Path)
throw 'Cannot process argument because the value of argument "path" is not valid. Change the value of the "path" argument and run the operation again.'
} -ParameterFilter {$Path -eq $null}
# Pester 6 no longer falls through to the real command when no filter matches
Mock Get-ChildItem { & (Get-Command Get-ChildItem -CommandType Cmdlet) @PesterBoundParameters }

{
$script:res = Test-AdfCode -RootFolder $RootFolder -ConfigPath $null
Expand Down
8 changes: 2 additions & 6 deletions test/TestHelper/TestHelper.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,8 @@ function Restore-File {
}

function Get-RootPath {
$rootPath = Switch ($Host.name) {
'Visual Studio Code Host' { Split-Path $psEditor.GetEditorContext().CurrentFile.Path }
'Windows PowerShell ISE Host' { Split-Path -Path $psISE.CurrentFile.FullPath }
'ConsoleHost' { $PSScriptRoot }
}
#$rootPath = Split-Path $rootPath -Parent
# 'test' folder (parent of TestHelper), independent of the host/active editor
$rootPath = Split-Path $PSScriptRoot -Parent
return $rootPath;
}

Expand Down
2 changes: 1 addition & 1 deletion test/Triggers_template.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ if ($ShouldThrow) {
} | Should -Not -Throw
}

Assert-MockCalled Stop-Trigger -Times ([int]$ExpectDisableTrigger)
Should -Invoke Stop-Trigger -Times ([int]$ExpectDisableTrigger)

$script:TriggersOnDiskCount = (Get-ChildItem -Path "$RootFolder\trigger" -Filter "$triggerName.json" -Recurse:$true | Measure-Object).Count
$tr = Get-AzDataFactoryV2Trigger @script:CommonParam
Expand Down
6 changes: 3 additions & 3 deletions test/Update-PropertiesFromFile.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ InModuleScope azure.datafactory.tools {
}
It 'Should execute Update-PropertiesForObject 3 times' {
Update-PropertiesFromFile -adf $script:adf -stage "multiple"
Assert-MockCalled Update-PropertiesForObject -Times 3
Should -Invoke Update-PropertiesForObject -Times 3
}
}

Expand All @@ -215,7 +215,7 @@ InModuleScope azure.datafactory.tools {
}
It 'Should execute Update-PropertiesForObject 4 times' {
Update-PropertiesFromFile -adf $script:adf -stage "array"
Assert-MockCalled Update-PropertiesForObject -Times 4
Should -Invoke Update-PropertiesForObject -Times 4
}
}
Context 'When called and CSV has array indexers in object name column' {
Expand Down Expand Up @@ -320,7 +320,7 @@ InModuleScope azure.datafactory.tools {
# }
# It 'Should execute Update-PropertiesForObject 3 times' {
# Update-PropertiesFromFile -adf $script:adf -stage "multiple"
# Assert-MockCalled Update-PropertiesForObject -Times 3
# Should -Invoke Update-PropertiesForObject -Times 3
# }
# }

Expand Down
10 changes: 5 additions & 5 deletions test/zGet-AdfFromService.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ InModuleScope azure.datafactory.tools {

It 'Should call Invoke-AzRestMethod with the correct datasets URL' {
Get-AdfFromService -FactoryName 'adf-test' -ResourceGroupName 'rg-test'
Assert-MockCalled Invoke-AzRestMethod -Times 1 -Exactly -ParameterFilter {
Should -Invoke Invoke-AzRestMethod -Times 1 -Exactly -ParameterFilter {
$Uri -like '*/datasets?api-version=2018-06-01'
}
}
Expand Down Expand Up @@ -213,7 +213,7 @@ InModuleScope azure.datafactory.tools {

It 'Should call Invoke-AzRestMethod exactly once' {
Get-AdfObjectsFromServiceRestAPI -adfi $script:fakeAdfi -typePlural 'datasets' -simpleType 'Dataset'
Assert-MockCalled Invoke-AzRestMethod -Times 1 -Exactly
Should -Invoke Invoke-AzRestMethod -Times 1 -Exactly
}
}

Expand Down Expand Up @@ -246,7 +246,7 @@ InModuleScope azure.datafactory.tools {

It 'Should call Invoke-AzRestMethod exactly once (no extra pages)' {
Get-AdfObjectsFromServiceRestAPI -adfi $script:fakeAdfi -typePlural 'datasets' -simpleType 'Dataset'
Assert-MockCalled Invoke-AzRestMethod -Times 1 -Exactly
Should -Invoke Invoke-AzRestMethod -Times 1 -Exactly
}
}

Expand Down Expand Up @@ -280,12 +280,12 @@ InModuleScope azure.datafactory.tools {

It 'Should call Invoke-AzRestMethod twice (once per page)' {
Get-AdfObjectsFromServiceRestAPI -adfi $script:fakeAdfi -typePlural 'datasets' -simpleType 'Dataset'
Assert-MockCalled Invoke-AzRestMethod -Times 2 -Exactly
Should -Invoke Invoke-AzRestMethod -Times 2 -Exactly
}

It 'Should use the nextLink URL for the second request' {
Get-AdfObjectsFromServiceRestAPI -adfi $script:fakeAdfi -typePlural 'datasets' -simpleType 'Dataset'
Assert-MockCalled Invoke-AzRestMethod -Times 1 -Exactly -ParameterFilter {
Should -Invoke Invoke-AzRestMethod -Times 1 -Exactly -ParameterFilter {
$Uri -eq $script:page2Url
}
}
Expand Down
Loading