diff --git a/.github/instructions/SqlServerDsc-guidelines.instructions.md b/.github/instructions/SqlServerDsc-guidelines.instructions.md index d5501c63c3..635b2dc02e 100644 --- a/.github/instructions/SqlServerDsc-guidelines.instructions.md +++ b/.github/instructions/SqlServerDsc-guidelines.instructions.md @@ -37,7 +37,6 @@ applyTo: "**" - Unit tests: Add `$env:SqlServerDscCI = $true` in `BeforeAll`, remove in `AfterAll` - Integration tests: - Use `Connect-SqlDscDatabaseEngine` for SQL Server DB session, and always with correct CI credentials - - Use `Disconnect-SqlDscDatabaseEngine` after `Connect-SqlDscDatabaseEngine` - Test config: tests/Integration/Commands/README.md and tests/Integration/Resources/README.md - Integration test script files must be added to a group within the test stage in ./azure-pipelines.yml. - Choose the appropriate group number based on the required dependencies diff --git a/CHANGELOG.md b/CHANGELOG.md index 8966c34816..1e086072a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - SqlServerDsc - Refactor integration tests for _SQL Server Reporting Services_ and _Power BI_ _Report Server_ ([issue #2431](https://github.com/dsccommunity/SqlServerDsc/issues/2431)). + - `Connect-Sql` create connection and server objects as per documentation. + - `Invoke-SqlDscQuery` remove disconnect as there is not an explicit connect. ## [17.4.0] - 2026-01-19 diff --git a/source/Modules/SqlServerDsc.Common/Public/Connect-Sql.ps1 b/source/Modules/SqlServerDsc.Common/Public/Connect-Sql.ps1 index c17056ae8c..2ecb5619e4 100644 --- a/source/Modules/SqlServerDsc.Common/Public/Connect-Sql.ps1 +++ b/source/Modules/SqlServerDsc.Common/Public/Connect-Sql.ps1 @@ -48,6 +48,7 @@ function Connect-Sql { [CmdletBinding(DefaultParameterSetName = 'SqlServer')] + [OutputType([System.Object])] param ( [Parameter(ParameterSetName = 'SqlServer')] @@ -127,8 +128,7 @@ function Connect-Sql $databaseEngineInstance = '{0}:{1}' -f $Protocol, $databaseEngineInstance } - $sqlServerObject = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server' - $sqlConnectionContext = $sqlServerObject.ConnectionContext + $sqlConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Common.ServerConnection $sqlConnectionContext.ServerInstance = $databaseEngineInstance $sqlConnectionContext.StatementTimeout = $StatementTimeout $sqlConnectionContext.ConnectTimeout = $StatementTimeout @@ -179,14 +179,16 @@ function Connect-Sql { $onlineStatus = 'Online' $connectTimer = [System.Diagnostics.StopWatch]::StartNew() - $sqlConnectionContext.Connect() + $sqlServerObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $sqlConnectionContext <# - The addition of the ConnectTimeout property to the ConnectionContext will force the - Connect() method to block until successful. THe SMO object's Status property may not - report 'Online' immediately even though the Connect() was successful. The loop is to - ensure the SMO's Status property was been updated. + The addition of the ConnectTimeout property to the ConnectionContext will force the + Connect() method to block until successful. The SMO object's Status property may not + report 'Online' immediately even though the Connect() was successful. The loop is to + ensure the SMO's Status property was been updated. #> + $sqlServerObject.ConnectionContext.Connect() + $sleepInSeconds = 2 do { @@ -270,12 +272,12 @@ function Connect-Sql { $connectTimer.Stop() <# - Connect will ensure we actually can connect, but we need to disconnect + Connect() will ensure we actually can connect, but we need to disconnect from the session so we don't have anything hanging. If we need run a method on the returned $sqlServerObject it will automatically open a new session and then close, therefore we don't need to keep this session open. #> - $sqlConnectionContext.Disconnect() + $sqlServerObject.ConnectionContext.Disconnect() } } diff --git a/source/Public/Invoke-SqlDscQuery.ps1 b/source/Public/Invoke-SqlDscQuery.ps1 index 6081e1041c..614ae9601e 100644 --- a/source/Public/Invoke-SqlDscQuery.ps1 +++ b/source/Public/Invoke-SqlDscQuery.ps1 @@ -270,12 +270,4 @@ function Invoke-SqlDscQuery } } } - - end - { - if ($PSCmdlet.ParameterSetName -eq 'ByServerName') - { - $ServerObject | Disconnect-SqlDscDatabaseEngine -Force -Verbose:$VerbosePreference - } - } } diff --git a/tests/Unit/DSC_SqlAGDatabase.Tests.ps1 b/tests/Unit/DSC_SqlAGDatabase.Tests.ps1 index 5dc3d2b863..78f3cc6a10 100644 --- a/tests/Unit/DSC_SqlAGDatabase.Tests.ps1 +++ b/tests/Unit/DSC_SqlAGDatabase.Tests.ps1 @@ -83,7 +83,7 @@ try #region Availability Replica Mocks $mockAvailabilityReplicaObjects = New-Object -TypeName Microsoft.SqlServer.Management.Smo.AvailabilityReplicaCollection - foreach ( $mockAvailabilityReplicaName in @('Server1','Server2') ) + foreach ( $mockAvailabilityReplicaName in @('Server1', 'Server2') ) { $newAvailabilityReplicaObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.AvailabilityReplica $newAvailabilityReplicaObject.Name = $mockAvailabilityReplicaName @@ -246,7 +246,7 @@ try $mockMasterDatabaseObject1.ID = 1 $mockMasterDatabaseObject1.Certificates = @($mockCertificateObject1) $mockMasterDatabaseObject1.FileGroups = @{ - Name = 'PRIMARY' + Name = 'PRIMARY' Files = @{ FileName = ( [IO.Path]::Combine( $mockDataFilePath, "$($mockMasterDatabaseName).mdf" ) ) } @@ -261,7 +261,7 @@ try $newDatabaseObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Database $newDatabaseObject.Name = $mockPresentDatabaseName $newDatabaseObject.FileGroups = @{ - Name = 'PRIMARY' + Name = 'PRIMARY' Files = @{ FileName = ( [IO.Path]::Combine( $mockDataFilePath, "$($mockPresentDatabaseName).mdf" ) ) } @@ -282,7 +282,7 @@ try $newDatabaseObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Database $newDatabaseObject.Name = $mockPresentDatabaseName $newDatabaseObject.FileGroups = @{ - Name = 'PRIMARY' + Name = 'PRIMARY' Files = @{ FileName = ( [IO.Path]::Combine( $mockDataFilePathIncorrect, "$($mockPresentDatabaseName).mdf" ) ) } @@ -307,7 +307,7 @@ try $mockServerObject.AvailabilityGroups.Add($mockAvailabilityGroupWithoutDatabasesObject.Clone()) $mockServerObject.AvailabilityGroups.Add($mockAvailabilityGroupObjectWithPrimaryReplicaOnAnotherServer.Clone()) $mockServerObject.ComputerNamePhysicalNetBIOS = $mockServerObjectDomainInstanceName - $mockServerObject.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ServerConnection + $mockServerObject.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Common.ServerConnection $mockServerObject.ConnectionContext.TrueLogin = $mockTrueLogin $mockServerObject.Databases = $mockDatabaseObjects $mockServerObject.DomainInstanceName = $mockServerObjectDomainInstanceName @@ -323,7 +323,7 @@ try $mockServer2Object.AvailabilityGroups.Add($mockAvailabilityGroupWithoutDatabasesObject.Clone()) $mockServer2Object.AvailabilityGroups.Add($mockAvailabilityGroupObjectWithPrimaryReplicaOnAnotherServer.Clone()) $mockServer2Object.ComputerNamePhysicalNetBIOS = $mockPrimaryServerObjectDomainInstanceName - $mockServer2Object.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ServerConnection + $mockServer2Object.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Common.ServerConnection $mockServer2Object.ConnectionContext.TrueLogin = $mockTrueLogin $mockServer2Object.Databases = $mockDatabaseObjects $mockServer2Object.DomainInstanceName = $mockPrimaryServerObjectDomainInstanceName @@ -380,11 +380,11 @@ REVERT' BeforeEach { $getTargetResourceParameters = @{ - DatabaseName = $mockDatabaseNameParameter.Clone() - ServerName = 'Server1' - InstanceName = 'MSSQLSERVER' + DatabaseName = $mockDatabaseNameParameter.Clone() + ServerName = 'Server1' + InstanceName = 'MSSQLSERVER' AvailabilityGroupName = 'AvailabilityGroup1' - BackupPath = $($mockBackupPath) + BackupPath = $($mockBackupPath) } } @@ -479,7 +479,7 @@ REVERT' #region Availability Replica Mocks $mockAvailabilityReplicaObjects = New-Object -TypeName Microsoft.SqlServer.Management.Smo.AvailabilityReplicaCollection - foreach ( $mockAvailabilityReplicaName in @('Server1','Server2') ) + foreach ( $mockAvailabilityReplicaName in @('Server1', 'Server2') ) { $newAvailabilityReplicaObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.AvailabilityReplica $newAvailabilityReplicaObject.Name = $mockAvailabilityReplicaName @@ -642,7 +642,7 @@ REVERT' $mockMasterDatabaseObject1.ID = 1 $mockMasterDatabaseObject1.Certificates = @($mockCertificateObject1) $mockMasterDatabaseObject1.FileGroups = @{ - Name = 'PRIMARY' + Name = 'PRIMARY' Files = @{ FileName = ( [IO.Path]::Combine( $mockDataFilePath, "$($mockMasterDatabaseName).mdf" ) ) } @@ -657,7 +657,7 @@ REVERT' $newDatabaseObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Database $newDatabaseObject.Name = $mockPresentDatabaseName $newDatabaseObject.FileGroups = @{ - Name = 'PRIMARY' + Name = 'PRIMARY' Files = @{ FileName = ( [IO.Path]::Combine( $mockDataFilePath, "$($mockPresentDatabaseName).mdf" ) ) } @@ -678,7 +678,7 @@ REVERT' $newDatabaseObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Database $newDatabaseObject.Name = $mockPresentDatabaseName $newDatabaseObject.FileGroups = @{ - Name = 'PRIMARY' + Name = 'PRIMARY' Files = @{ FileName = ( [IO.Path]::Combine( $mockDataFilePathIncorrect, "$($mockPresentDatabaseName).mdf" ) ) } @@ -703,7 +703,7 @@ REVERT' $mockServerObject.AvailabilityGroups.Add($mockAvailabilityGroupWithoutDatabasesObject.Clone()) $mockServerObject.AvailabilityGroups.Add($mockAvailabilityGroupObjectWithPrimaryReplicaOnAnotherServer.Clone()) $mockServerObject.ComputerNamePhysicalNetBIOS = $mockServerObjectDomainInstanceName - $mockServerObject.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ServerConnection + $mockServerObject.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Common.ServerConnection $mockServerObject.ConnectionContext.TrueLogin = $mockTrueLogin $mockServerObject.Databases = $mockDatabaseObjects $mockServerObject.DomainInstanceName = $mockServerObjectDomainInstanceName @@ -719,7 +719,7 @@ REVERT' $mockServer2Object.AvailabilityGroups.Add($mockAvailabilityGroupWithoutDatabasesObject.Clone()) $mockServer2Object.AvailabilityGroups.Add($mockAvailabilityGroupObjectWithPrimaryReplicaOnAnotherServer.Clone()) $mockServer2Object.ComputerNamePhysicalNetBIOS = $mockPrimaryServerObjectDomainInstanceName - $mockServer2Object.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ServerConnection + $mockServer2Object.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Common.ServerConnection $mockServer2Object.ConnectionContext.TrueLogin = $mockTrueLogin $mockServer2Object.Databases = $mockDatabaseObjects $mockServer2Object.DomainInstanceName = $mockPrimaryServerObjectDomainInstanceName @@ -775,22 +775,22 @@ REVERT' Mock -CommandName Import-SqlDscPreferredModule -Verifiable Mock -CommandName Invoke-SqlDscQuery -Verifiable -ParameterFilter $mockInvokeQueryParameterRestoreDatabase Mock -CommandName invokeSqlDscQueryParameters -Verifiable -ParameterFilter $mockInvokeQueryParameterRestoreDatabaseWithExecuteAs - Mock -CommandName Join-Path -MockWith { [IO.Path]::Combine($databaseMembershipClass.BackupPath,"$($database.Name)_Full_$(Get-Date -Format 'yyyyMMddhhmmss').bak") } -Verifiable -ParameterFilter { $ChildPath -like '*_Full_*.bak' } - Mock -CommandName Join-Path -MockWith { [IO.Path]::Combine($databaseMembershipClass.BackupPath,"$($database.Name)_Log_$(Get-Date -Format 'yyyyMMddhhmmss').trn") } -Verifiable -ParameterFilter { $ChildPath -like '*_Log_*.trn' } + Mock -CommandName Join-Path -MockWith { [IO.Path]::Combine($databaseMembershipClass.BackupPath, "$($database.Name)_Full_$(Get-Date -Format 'yyyyMMddhhmmss').bak") } -Verifiable -ParameterFilter { $ChildPath -like '*_Full_*.bak' } + Mock -CommandName Join-Path -MockWith { [IO.Path]::Combine($databaseMembershipClass.BackupPath, "$($database.Name)_Log_$(Get-Date -Format 'yyyyMMddhhmmss').trn") } -Verifiable -ParameterFilter { $ChildPath -like '*_Log_*.trn' } Mock -CommandName Remove-Item -Verifiable } BeforeEach { $mockSetTargetResourceParameters = @{ - DatabaseName = $($mockDatabaseNameParameter) - ServerName = $($mockServerObject.DomainInstanceName) - InstanceName = $('MSSQLSERVER') + DatabaseName = $($mockDatabaseNameParameter) + ServerName = $($mockServerObject.DomainInstanceName) + InstanceName = $('MSSQLSERVER') AvailabilityGroupName = $($mockAvailabilityGroupObjectName) - BackupPath = $($mockBackupPath) - Ensure = 'Present' - Force = $false - MatchDatabaseOwner = $true - ReplaceExisting = $false + BackupPath = $($mockBackupPath) + Ensure = 'Present' + Force = $false + MatchDatabaseOwner = $true + ReplaceExisting = $false } Mock -CommandName Add-SqlAvailabilityDatabase -Verifiable -ParameterFilter { $InputObject.PrimaryReplicaServerName -eq 'Server1' -and $InputObject.LocalReplicaRole -eq 'Primary' } @@ -798,7 +798,7 @@ REVERT' Mock -CommandName Add-SqlAvailabilityDatabase -Verifiable -ParameterFilter { $InputObject.PrimaryReplicaServerName -eq 'Server2' -and $InputObject.LocalReplicaRole -eq 'Primary' } Mock -CommandName Add-SqlAvailabilityDatabase -Verifiable -ParameterFilter { $InputObject.PrimaryReplicaServerName -eq 'Server2' -and $InputObject.LocalReplicaRole -eq 'Secondary' } Mock -CommandName Backup-SqlDatabase -Verifiable -ParameterFilter { $BackupAction -eq 'Database' } - Mock -CommandName Backup-SqlDatabase -Verifiable -ParameterFilter { $BackupAction -eq 'Log'} + Mock -CommandName Backup-SqlDatabase -Verifiable -ParameterFilter { $BackupAction -eq 'Log' } Mock -CommandName Connect-SQL -MockWith { return $mockServerObject } -Verifiable -ParameterFilter { $ServerName -eq 'Server1' -and $InstanceName -eq 'MSSQLSERVER' } Mock -CommandName Connect-SQL -MockWith { return $mockServerObject } -Verifiable -ParameterFilter { $ServerName -eq 'Server1' } Mock -CommandName Connect-SQL -MockWith { return $mockServer2Object } -Verifiable -ParameterFilter { $ServerName -eq 'Server2' } @@ -970,12 +970,12 @@ REVERT' } $prerequisiteChecks = @{ - RecoveryModel = 'Full' - ReadOnly = $false - UserAccess = 'Multiple' - AutoClose = $false + RecoveryModel = 'Full' + ReadOnly = $false + UserAccess = 'Multiple' + AutoClose = $false AvailabilityGroupName = '' - IsMirroringEnabled = $false + IsMirroringEnabled = $false } foreach ( $prerequisiteCheck in $prerequisiteChecks.GetEnumerator() ) @@ -1017,7 +1017,7 @@ REVERT' Assert-MockCalled -CommandName Join-Path -Scope It -Times 0 -Exactly -ParameterFilter { $ChildPath -like '*_Log_*.trn' } Assert-MockCalled -CommandName Remove-Item -Scope It -Times 0 -Exactly Assert-MockCalled -CommandName Remove-SqlAvailabilityDatabase -Scope It -Times 0 -Exactly - Assert-MockCalled -CommandName Test-ImpersonatePermissions -Scope It -Times 1 -Exactly + Assert-MockCalled -CommandName Test-ImpersonatePermissions -Scope It -Times 1 -Exactly $mockServerObject.Databases['DB1'].($prerequisiteCheck.Key) = $originalValue } @@ -1051,8 +1051,8 @@ REVERT' } $filestreamProperties = @{ - DefaultFileStreamFileGroup = '' - FilestreamDirectoryName = '' + DefaultFileStreamFileGroup = '' + FilestreamDirectoryName = '' FilestreamNonTransactedAccess = 'Off' } @@ -1083,7 +1083,7 @@ REVERT' Assert-MockCalled -CommandName Join-Path -Scope It -Times 0 -Exactly -ParameterFilter { $ChildPath -like '*_Log_*.trn' } Assert-MockCalled -CommandName Remove-Item -Scope It -Times 0 -Exactly Assert-MockCalled -CommandName Remove-SqlAvailabilityDatabase -Scope It -Times 0 -Exactly - Assert-MockCalled -CommandName Test-ImpersonatePermissions -Scope It -Times 1 -Exactly + Assert-MockCalled -CommandName Test-ImpersonatePermissions -Scope It -Times 1 -Exactly $mockServerObject.Databases['DB1'].($filestreamProperty.Key) = $originalValue } @@ -1122,7 +1122,7 @@ REVERT' It 'Should throw the correct error when the database file path does not exist on the secondary replica' { Mock -CommandName Invoke-SqlDscQuery -MockWith $mockResultInvokeQueryFileNotExist -Verifiable -ParameterFilter { $Query -like 'EXEC master.dbo.xp_fileexist *' } $originalValue = $mockServer2Object.Databases['DB1'].FileGroups.Files.FileName - $mockServer2Object.Databases['DB1'].FileGroups.Files.FileName = ( [IO.Path]::Combine( 'X:\', "DB1.mdf" ) ) + $mockServer2Object.Databases['DB1'].FileGroups.Files.FileName = ( [IO.Path]::Combine( 'X:\', 'DB1.mdf' ) ) { Set-TargetResource @mockSetTargetResourceParameters } | Should -Throw "The operation on the database 'DB1' failed with the following errors: The following prerequisite checks failed: The instance 'Server2' is missing the following directories: X:\, F:\SqlLog" @@ -1153,7 +1153,7 @@ REVERT' It 'Should throw the correct error when the log file path does not exist on the secondary replica' { Mock -CommandName Invoke-SqlDscQuery -MockWith $mockResultInvokeQueryFileNotExist -Verifiable -ParameterFilter { $Query -like 'EXEC master.dbo.xp_fileexist *' } $originalValue = $mockServer2Object.Databases['DB1'].LogFiles.FileName - $mockServer2Object.Databases['DB1'].LogFiles.FileName = ( [IO.Path]::Combine( 'Y:\', "DB1.ldf" ) ) + $mockServer2Object.Databases['DB1'].LogFiles.FileName = ( [IO.Path]::Combine( 'Y:\', 'DB1.ldf' ) ) { Set-TargetResource @mockSetTargetResourceParameters } | Should -Throw 'The operation on the database ''DB1'' failed with the following errors: The following prerequisite checks failed: The instance ''Server2'' is missing the following directories: E:\SqlData, Y:\' @@ -1424,7 +1424,7 @@ REVERT' $mockServerObject_Set.AvailabilityGroups = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.AvailabilityGroupCollection' $mockServerObject_Set.AvailabilityGroups.Add($mockAvailabilityGroupObject_Set.Clone()) $mockServerObject_Set.ComputerNamePhysicalNetBIOS = 'Server1' - $mockServerObject_Set.ConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.ServerConnection' + $mockServerObject_Set.ConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Common.ServerConnection' $mockServerObject_Set.ConnectionContext.TrueLogin = 'Login1' $mockServerObject_Set.DomainInstanceName = 'Server1' $mockServerObject_Set.NetName = 'Server1' @@ -1453,14 +1453,14 @@ REVERT' } $mockSetTargetResourceParameters = @{ - DatabaseName = @('DB2') - ServerName = 'Server1' - InstanceName = 'MSSQLSERVER' + DatabaseName = @('DB2') + ServerName = 'Server1' + InstanceName = 'MSSQLSERVER' AvailabilityGroupName = 'AvailabilityGroup1' - BackupPath = 'X:\Backup' - Ensure = 'Absent' - Force = $false - Verbose = $true + BackupPath = 'X:\Backup' + Ensure = 'Absent' + Force = $false + Verbose = $true } } @@ -1500,9 +1500,9 @@ REVERT' } } } -# } + # } -# Describe 'SqlAGDatabase\Set-TargetResource' -Tag 'Set Automatic' { + # Describe 'SqlAGDatabase\Set-TargetResource' -Tag 'Set Automatic' { Context 'Tests that was moved into its own context block to prevent intermittent fails (see issue #1532) - workaround until proper refactor with seeding on automatic' { BeforeAll { #region Parameter Mocks @@ -1541,7 +1541,7 @@ REVERT' #region Availability Replica Mocks $mockAvailabilityReplicaObjects = New-Object -TypeName Microsoft.SqlServer.Management.Smo.AvailabilityReplicaCollection - foreach ( $mockAvailabilityReplicaName in @('Server1','Server2') ) + foreach ( $mockAvailabilityReplicaName in @('Server1', 'Server2') ) { $newAvailabilityReplicaObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.AvailabilityReplica $newAvailabilityReplicaObject.Name = $mockAvailabilityReplicaName @@ -1703,7 +1703,7 @@ REVERT' $mockMasterDatabaseObject1.ID = 1 $mockMasterDatabaseObject1.Certificates = @($mockCertificateObject1) $mockMasterDatabaseObject1.FileGroups = @{ - Name = 'PRIMARY' + Name = 'PRIMARY' Files = @{ FileName = ( [IO.Path]::Combine( $mockDataFilePath, "$($mockMasterDatabaseName).mdf" ) ) } @@ -1718,7 +1718,7 @@ REVERT' $newDatabaseObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Database $newDatabaseObject.Name = $mockPresentDatabaseName $newDatabaseObject.FileGroups = @{ - Name = 'PRIMARY' + Name = 'PRIMARY' Files = @{ FileName = ( [IO.Path]::Combine( $mockDataFilePath, "$($mockPresentDatabaseName).mdf" ) ) } @@ -1739,7 +1739,7 @@ REVERT' $newDatabaseObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Database $newDatabaseObject.Name = $mockPresentDatabaseName $newDatabaseObject.FileGroups = @{ - Name = 'PRIMARY' + Name = 'PRIMARY' Files = @{ FileName = ( [IO.Path]::Combine( $mockDataFilePathIncorrect, "$($mockPresentDatabaseName).mdf" ) ) } @@ -1764,7 +1764,7 @@ REVERT' $mockServerObject.AvailabilityGroups.Add($mockAvailabilityGroupWithoutDatabasesObject.Clone()) $mockServerObject.AvailabilityGroups.Add($mockAvailabilityGroupObjectWithPrimaryReplicaOnAnotherServer.Clone()) $mockServerObject.ComputerNamePhysicalNetBIOS = $mockServerObjectDomainInstanceName - $mockServerObject.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ServerConnection + $mockServerObject.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Common.ServerConnection $mockServerObject.ConnectionContext.TrueLogin = $mockTrueLogin $mockServerObject.Databases = $mockDatabaseObjects $mockServerObject.DomainInstanceName = $mockServerObjectDomainInstanceName @@ -1780,7 +1780,7 @@ REVERT' $mockServer2Object.AvailabilityGroups.Add($mockAvailabilityGroupWithoutDatabasesObject.Clone()) $mockServer2Object.AvailabilityGroups.Add($mockAvailabilityGroupObjectWithPrimaryReplicaOnAnotherServer.Clone()) $mockServer2Object.ComputerNamePhysicalNetBIOS = $mockPrimaryServerObjectDomainInstanceName - $mockServer2Object.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ServerConnection + $mockServer2Object.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Common.ServerConnection $mockServer2Object.ConnectionContext.TrueLogin = $mockTrueLogin $mockServer2Object.Databases = $mockDatabaseObjects $mockServer2Object.DomainInstanceName = $mockPrimaryServerObjectDomainInstanceName @@ -1835,22 +1835,22 @@ REVERT' Mock -CommandName Import-SqlDscPreferredModule -Verifiable Mock -CommandName Invoke-SqlDscQuery -Verifiable -ParameterFilter $mockInvokeQueryParameterRestoreDatabase Mock -CommandName Invoke-SqlDscQuery -Verifiable -ParameterFilter $mockInvokeQueryParameterRestoreDatabaseWithExecuteAs - Mock -CommandName Join-Path -MockWith { [IO.Path]::Combine($databaseMembershipClass.BackupPath,"$($database.Name)_Full_$(Get-Date -Format 'yyyyMMddhhmmss').bak") } -Verifiable -ParameterFilter { $ChildPath -like '*_Full_*.bak' } - Mock -CommandName Join-Path -MockWith { [IO.Path]::Combine($databaseMembershipClass.BackupPath,"$($database.Name)_Log_$(Get-Date -Format 'yyyyMMddhhmmss').trn") } -Verifiable -ParameterFilter { $ChildPath -like '*_Log_*.trn' } + Mock -CommandName Join-Path -MockWith { [IO.Path]::Combine($databaseMembershipClass.BackupPath, "$($database.Name)_Full_$(Get-Date -Format 'yyyyMMddhhmmss').bak") } -Verifiable -ParameterFilter { $ChildPath -like '*_Full_*.bak' } + Mock -CommandName Join-Path -MockWith { [IO.Path]::Combine($databaseMembershipClass.BackupPath, "$($database.Name)_Log_$(Get-Date -Format 'yyyyMMddhhmmss').trn") } -Verifiable -ParameterFilter { $ChildPath -like '*_Log_*.trn' } Mock -CommandName Remove-Item -Verifiable } BeforeEach { $mockSetTargetResourceParameters = @{ - DatabaseName = $($mockDatabaseNameParameter) - ServerName = $($mockServerObject.DomainInstanceName) - InstanceName = $('MSSQLSERVER') + DatabaseName = $($mockDatabaseNameParameter) + ServerName = $($mockServerObject.DomainInstanceName) + InstanceName = $('MSSQLSERVER') AvailabilityGroupName = $($mockAvailabilityGroupObjectName) - BackupPath = $($mockBackupPath) - Ensure = 'Present' - Force = $false - MatchDatabaseOwner = $true - ReplaceExisting = $false + BackupPath = $($mockBackupPath) + Ensure = 'Present' + Force = $false + MatchDatabaseOwner = $true + ReplaceExisting = $false } Mock -CommandName Add-SqlAvailabilityDatabase -Verifiable -ParameterFilter { $InputObject.PrimaryReplicaServerName -eq 'Server1' -and $InputObject.LocalReplicaRole -eq 'Primary' } @@ -1858,7 +1858,7 @@ REVERT' Mock -CommandName Add-SqlAvailabilityDatabase -Verifiable -ParameterFilter { $InputObject.PrimaryReplicaServerName -eq 'Server2' -and $InputObject.LocalReplicaRole -eq 'Primary' } Mock -CommandName Add-SqlAvailabilityDatabase -Verifiable -ParameterFilter { $InputObject.PrimaryReplicaServerName -eq 'Server2' -and $InputObject.LocalReplicaRole -eq 'Secondary' } Mock -CommandName Backup-SqlDatabase -Verifiable -ParameterFilter { $BackupAction -eq 'Database' } - Mock -CommandName Backup-SqlDatabase -Verifiable -ParameterFilter { $BackupAction -eq 'Log'} + Mock -CommandName Backup-SqlDatabase -Verifiable -ParameterFilter { $BackupAction -eq 'Log' } Mock -CommandName Connect-SQL -MockWith { return $mockServerObject } -Verifiable -ParameterFilter { $ServerName -eq 'Server1' -and $InstanceName -eq 'MSSQLSERVER' } Mock -CommandName Connect-SQL -MockWith { return $mockServerObject } -Verifiable -ParameterFilter { $ServerName -eq 'Server1' } Mock -CommandName Connect-SQL -MockWith { return $mockServer2Object } -Verifiable -ParameterFilter { $ServerName -eq 'Server2' } @@ -1868,7 +1868,7 @@ REVERT' } Context 'When Ensure is Present' { - It 'Should add the specified databases to the availability group.' { + It 'Should add the specified databases to the availability group.' { $null = Set-TargetResource @mockSetTargetResourceParameters -ErrorAction 'Stop' Assert-MockCalled -CommandName Add-SqlAvailabilityDatabase -Scope It -Times 1 -Exactly -ParameterFilter { $InputObject.PrimaryReplicaServerName -eq 'Server1' -and $InputObject.LocalReplicaRole -eq 'Primary' } @@ -2030,12 +2030,12 @@ REVERT' } $prerequisiteChecks = @{ - RecoveryModel = 'Full' - ReadOnly = $false - UserAccess = 'Multiple' - AutoClose = $false + RecoveryModel = 'Full' + ReadOnly = $false + UserAccess = 'Multiple' + AutoClose = $false AvailabilityGroupName = '' - IsMirroringEnabled = $false + IsMirroringEnabled = $false } foreach ( $prerequisiteCheck in $prerequisiteChecks.GetEnumerator() ) @@ -2077,7 +2077,7 @@ REVERT' Assert-MockCalled -CommandName Join-Path -Scope It -Times 0 -Exactly -ParameterFilter { $ChildPath -like '*_Log_*.trn' } Assert-MockCalled -CommandName Remove-Item -Scope It -Times 0 -Exactly Assert-MockCalled -CommandName Remove-SqlAvailabilityDatabase -Scope It -Times 0 -Exactly - Assert-MockCalled -CommandName Test-ImpersonatePermissions -Scope It -Times 1 -Exactly + Assert-MockCalled -CommandName Test-ImpersonatePermissions -Scope It -Times 1 -Exactly $mockServerObject.Databases['DB1'].($prerequisiteCheck.Key) = $originalValue } @@ -2111,8 +2111,8 @@ REVERT' } $filestreamProperties = @{ - DefaultFileStreamFileGroup = '' - FilestreamDirectoryName = '' + DefaultFileStreamFileGroup = '' + FilestreamDirectoryName = '' FilestreamNonTransactedAccess = 'Off' } @@ -2143,7 +2143,7 @@ REVERT' Assert-MockCalled -CommandName Join-Path -Scope It -Times 0 -Exactly -ParameterFilter { $ChildPath -like '*_Log_*.trn' } Assert-MockCalled -CommandName Remove-Item -Scope It -Times 0 -Exactly Assert-MockCalled -CommandName Remove-SqlAvailabilityDatabase -Scope It -Times 0 -Exactly - Assert-MockCalled -CommandName Test-ImpersonatePermissions -Scope It -Times 1 -Exactly + Assert-MockCalled -CommandName Test-ImpersonatePermissions -Scope It -Times 1 -Exactly $mockServerObject.Databases['DB1'].($filestreamProperty.Key) = $originalValue } @@ -2182,7 +2182,7 @@ REVERT' It 'Should throw the correct error when the database file path does not exist on the secondary replica' { Mock -CommandName Invoke-SqlDscQuery -MockWith $mockResultInvokeQueryFileNotExist -Verifiable -ParameterFilter { $Query -like 'EXEC master.dbo.xp_fileexist *' } $originalValue = $mockServer2Object.Databases['DB1'].FileGroups.Files.FileName - $mockServer2Object.Databases['DB1'].FileGroups.Files.FileName = ( [IO.Path]::Combine( 'X:\', "DB1.mdf" ) ) + $mockServer2Object.Databases['DB1'].FileGroups.Files.FileName = ( [IO.Path]::Combine( 'X:\', 'DB1.mdf' ) ) { Set-TargetResource @mockSetTargetResourceParameters } | Should -Throw "The operation on the database 'DB1' failed with the following errors: The following prerequisite checks failed: The instance 'Server2' is missing the following directories: X:\, F:\SqlLog" @@ -2213,7 +2213,7 @@ REVERT' It 'Should throw the correct error when the log file path does not exist on the secondary replica' { Mock -CommandName Invoke-SqlDscQuery -MockWith $mockResultInvokeQueryFileNotExist -Verifiable -ParameterFilter { $Query -like 'EXEC master.dbo.xp_fileexist *' } $originalValue = $mockServer2Object.Databases['DB1'].LogFiles.FileName - $mockServer2Object.Databases['DB1'].LogFiles.FileName = ( [IO.Path]::Combine( 'Y:\', "DB1.ldf" ) ) + $mockServer2Object.Databases['DB1'].LogFiles.FileName = ( [IO.Path]::Combine( 'Y:\', 'DB1.ldf' ) ) { Set-TargetResource @mockSetTargetResourceParameters } | Should -Throw 'The operation on the database ''DB1'' failed with the following errors: The following prerequisite checks failed: The instance ''Server2'' is missing the following directories: E:\SqlData, Y:\' @@ -2433,7 +2433,7 @@ REVERT' #region Availability Replica Mocks $mockAvailabilityReplicaObjects = New-Object -TypeName Microsoft.SqlServer.Management.Smo.AvailabilityReplicaCollection - foreach ( $mockAvailabilityReplicaName in @('Server1','Server2') ) + foreach ( $mockAvailabilityReplicaName in @('Server1', 'Server2') ) { $newAvailabilityReplicaObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.AvailabilityReplica $newAvailabilityReplicaObject.Name = $mockAvailabilityReplicaName @@ -2596,7 +2596,7 @@ REVERT' $mockMasterDatabaseObject1.ID = 1 $mockMasterDatabaseObject1.Certificates = @($mockCertificateObject1) $mockMasterDatabaseObject1.FileGroups = @{ - Name = 'PRIMARY' + Name = 'PRIMARY' Files = @{ FileName = ( [IO.Path]::Combine( $mockDataFilePath, "$($mockMasterDatabaseName).mdf" ) ) } @@ -2611,7 +2611,7 @@ REVERT' $newDatabaseObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Database $newDatabaseObject.Name = $mockPresentDatabaseName $newDatabaseObject.FileGroups = @{ - Name = 'PRIMARY' + Name = 'PRIMARY' Files = @{ FileName = ( [IO.Path]::Combine( $mockDataFilePath, "$($mockPresentDatabaseName).mdf" ) ) } @@ -2632,7 +2632,7 @@ REVERT' $newDatabaseObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Database $newDatabaseObject.Name = $mockPresentDatabaseName $newDatabaseObject.FileGroups = @{ - Name = 'PRIMARY' + Name = 'PRIMARY' Files = @{ FileName = ( [IO.Path]::Combine( $mockDataFilePathIncorrect, "$($mockPresentDatabaseName).mdf" ) ) } @@ -2657,7 +2657,7 @@ REVERT' $mockServerObject.AvailabilityGroups.Add($mockAvailabilityGroupWithoutDatabasesObject.Clone()) $mockServerObject.AvailabilityGroups.Add($mockAvailabilityGroupObjectWithPrimaryReplicaOnAnotherServer.Clone()) $mockServerObject.ComputerNamePhysicalNetBIOS = $mockServerObjectDomainInstanceName - $mockServerObject.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ServerConnection + $mockServerObject.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Common.ServerConnection $mockServerObject.ConnectionContext.TrueLogin = $mockTrueLogin $mockServerObject.Databases = $mockDatabaseObjects $mockServerObject.DomainInstanceName = $mockServerObjectDomainInstanceName @@ -2673,7 +2673,7 @@ REVERT' $mockServer2Object.AvailabilityGroups.Add($mockAvailabilityGroupWithoutDatabasesObject.Clone()) $mockServer2Object.AvailabilityGroups.Add($mockAvailabilityGroupObjectWithPrimaryReplicaOnAnotherServer.Clone()) $mockServer2Object.ComputerNamePhysicalNetBIOS = $mockPrimaryServerObjectDomainInstanceName - $mockServer2Object.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ServerConnection + $mockServer2Object.ConnectionContext = New-Object -TypeName Microsoft.SqlServer.Management.Common.ServerConnection $mockServer2Object.ConnectionContext.TrueLogin = $mockTrueLogin $mockServer2Object.Databases = $mockDatabaseObjects $mockServer2Object.DomainInstanceName = $mockPrimaryServerObjectDomainInstanceName @@ -2736,14 +2736,14 @@ REVERT' BeforeEach { $mockTestTargetResourceParameters = @{ - DatabaseName = $mockDatabaseNameParameter.Clone() - ServerName = $mockServerObject.DomainInstanceName - InstanceName = 'MSSQLSERVER' - AvailabilityGroupName = $mockAvailabilityGroupObject.Name - BackupPath = $($mockBackupPath) - Ensure = 'Present' - Force = $false - MatchDatabaseOwner = $false + DatabaseName = $mockDatabaseNameParameter.Clone() + ServerName = $mockServerObject.DomainInstanceName + InstanceName = 'MSSQLSERVER' + AvailabilityGroupName = $mockAvailabilityGroupObject.Name + BackupPath = $($mockBackupPath) + Ensure = 'Present' + Force = $false + MatchDatabaseOwner = $false ProcessOnlyOnActiveNode = $false } @@ -2922,9 +2922,9 @@ REVERT' Describe 'SqlAGDatabase\Get-DatabasesToAddToAvailabilityGroup' { BeforeEach { $getDatabasesToAddToAvailabilityGroup = @{ - DatabaseName = $mockDatabaseNameParameter.Clone() - Ensure = 'Present' - ServerObject = $mockServerObject + DatabaseName = $mockDatabaseNameParameter.Clone() + Ensure = 'Present' + ServerObject = $mockServerObject AvailabilityGroup = $mockAvailabilityGroupObject } } @@ -2961,10 +2961,10 @@ REVERT' Describe 'SqlAGDatabase\Get-DatabasesToRemoveFromAvailabilityGroup' { BeforeEach { $getDatabasesToRemoveFromAvailabilityGroupParameters = @{ - DatabaseName = $mockDatabaseNameParameter.Clone() - Ensure = 'Present' - Force = $false - ServerObject = $mockServerObject + DatabaseName = $mockDatabaseNameParameter.Clone() + Ensure = 'Present' + Force = $false + ServerObject = $mockServerObject AvailabilityGroup = $mockAvailabilityGroupObject } } @@ -3051,18 +3051,18 @@ REVERT' } It 'Should return an empty object when no matching databases are found' { - $getMatchingDatabaseNamesParameters.DatabaseName = @('DatabaseNotHere') + $getMatchingDatabaseNamesParameters.DatabaseName = @('DatabaseNotHere') - Get-MatchingDatabaseNames @getMatchingDatabaseNamesParameters | Should -BeNullOrEmpty + Get-MatchingDatabaseNames @getMatchingDatabaseNamesParameters | Should -BeNullOrEmpty } It 'Should return an array of database names that match the defined databases' { - $results = Get-MatchingDatabaseNames @getMatchingDatabaseNamesParameters + $results = Get-MatchingDatabaseNames @getMatchingDatabaseNamesParameters - foreach ( $result in $results ) - { - $mockPresentDatabaseNames -contains $result | Should -BeTrue - } + foreach ( $result in $results ) + { + $mockPresentDatabaseNames -contains $result | Should -BeTrue + } } It 'Should return an array of database names that match the defined databases when the case does not match' { @@ -3074,7 +3074,7 @@ REVERT' { $mockPresentDatabaseNames -contains $result | Should -BeTrue } - } + } } } @@ -3090,7 +3090,7 @@ REVERT' BeforeEach { $getDatabaseNamesNotFoundOnTheInstanceParameters = @{ - DatabaseName = $mockDatabaseNameParameter.Clone() + DatabaseName = $mockDatabaseNameParameter.Clone() MatchingDatabaseNames = @() } } diff --git a/tests/Unit/Public/Disconnect-SqlDscDatabaseEngine.Tests.ps1 b/tests/Unit/Public/Disconnect-SqlDscDatabaseEngine.Tests.ps1 index 21e5d9c1f6..d7d85a6f38 100644 --- a/tests/Unit/Public/Disconnect-SqlDscDatabaseEngine.Tests.ps1 +++ b/tests/Unit/Public/Disconnect-SqlDscDatabaseEngine.Tests.ps1 @@ -52,7 +52,7 @@ AfterAll { Describe 'Disconnect-SqlDscDatabaseEngine' -Tag 'Public' { It 'Should have the correct parameters in parameter set ' -ForEach @( @{ - MockParameterSetName = '__AllParameterSets' + MockParameterSetName = '__AllParameterSets' # cSpell: disable-next MockExpectedParameters = '[-ServerObject] [-Force] [-WhatIf] [-Confirm] []' } @@ -63,11 +63,11 @@ Describe 'Disconnect-SqlDscDatabaseEngine' -Tag 'Public' { } | Select-Object -Property @( @{ - Name = 'ParameterSetName' + Name = 'ParameterSetName' Expression = { $_.Name } }, @{ - Name = 'ParameterListAsString' + Name = 'ParameterListAsString' Expression = { $_.ToString() } } ) @@ -81,7 +81,7 @@ Describe 'Disconnect-SqlDscDatabaseEngine' -Tag 'Public' { $mockServerObject = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server' $mockServerObject.InstanceName = 'MockInstance' - $mockConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.ServerConnection' | + $mockConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Common.ServerConnection' | Add-Member -MemberType 'ScriptMethod' -Name 'Disconnect' -Value { $script:mockMethodDisconnectCallCount += 1 } -PassThru -Force diff --git a/tests/Unit/Public/Invoke-SqlDscQuery.Tests.ps1 b/tests/Unit/Public/Invoke-SqlDscQuery.Tests.ps1 index 0eb8ccf9b6..d48506bc8c 100644 --- a/tests/Unit/Public/Invoke-SqlDscQuery.Tests.ps1 +++ b/tests/Unit/Public/Invoke-SqlDscQuery.Tests.ps1 @@ -103,7 +103,7 @@ Describe 'Invoke-SqlDscQuery' -Tag 'Public' { 'MockDatabase' = $databaseObject } -PassThru -Force - $mockConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.ServerConnection' | + $mockConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Common.ServerConnection' | Add-Member -MemberType 'NoteProperty' -Name 'StatementTimeout' -Value 100 -PassThru -Force $mockServerObject.ConnectionContext = $mockConnectionContext @@ -186,7 +186,6 @@ Describe 'Invoke-SqlDscQuery' -Tag 'Public' { $mockSqlCredentialSecurePassword = ConvertTo-SecureString -String $mockSqlCredentialPassword -AsPlainText -Force $mockSqlCredential = [System.Management.Automation.PSCredential]::new($mockSqlCredentialUserName, $mockSqlCredentialSecurePassword) - Mock -CommandName Disconnect-SqlDscDatabaseEngine Mock -CommandName Connect-SqlDscDatabaseEngine -MockWith { return $mockServerObject } @@ -200,7 +199,6 @@ Describe 'Invoke-SqlDscQuery' -Tag 'Public' { $mockMethodExecuteNonQueryCallCount | Should -Be 1 Should -Invoke -CommandName Connect-SqlDscDatabaseEngine -Exactly -Times 1 -Scope It - Should -Invoke -CommandName Disconnect-SqlDscDatabaseEngine -Exactly -Times 1 -Scope It } Context 'When calling the command with optional parameter Encrypt' { @@ -212,7 +210,6 @@ Describe 'Invoke-SqlDscQuery' -Tag 'Public' { $mockMethodExecuteNonQueryCallCount | Should -Be 1 Should -Invoke -CommandName Connect-SqlDscDatabaseEngine -Exactly -Times 1 -Scope It - Should -Invoke -CommandName Disconnect-SqlDscDatabaseEngine -Exactly -Times 1 -Scope It } } } @@ -240,7 +237,7 @@ Describe 'Invoke-SqlDscQuery' -Tag 'Public' { 'MockDatabase' = $databaseObject } -PassThru -Force - $mockConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.ServerConnection' | + $mockConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Common.ServerConnection' | Add-Member -MemberType 'NoteProperty' -Name 'StatementTimeout' -Value 100 -PassThru -Force $mockServerObject.ConnectionContext = $mockConnectionContext @@ -313,7 +310,7 @@ Describe 'Invoke-SqlDscQuery' -Tag 'Public' { 'MockDatabase' = $databaseObject } -PassThru -Force - $mockConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.ServerConnection' | + $mockConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Common.ServerConnection' | Add-Member -MemberType 'NoteProperty' -Name 'StatementTimeout' -Value 100 -PassThru -Force $mockServerObject.ConnectionContext = $mockConnectionContext diff --git a/tests/Unit/Public/Invoke-SqlDscScalarQuery.Tests.ps1 b/tests/Unit/Public/Invoke-SqlDscScalarQuery.Tests.ps1 index 13df53ccbc..895d602dfc 100644 --- a/tests/Unit/Public/Invoke-SqlDscScalarQuery.Tests.ps1 +++ b/tests/Unit/Public/Invoke-SqlDscScalarQuery.Tests.ps1 @@ -92,7 +92,7 @@ Describe 'Invoke-SqlDscScalarQuery' -Tag 'Public' { Context 'When executing a scalar query' { BeforeAll { - $mockConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.ServerConnection' + $mockConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Common.ServerConnection' $mockConnectionContext.StatementTimeout = 100 $mockConnectionContext | Add-Member -MemberType 'ScriptMethod' -Name 'ExecuteScalar' -Value { param @@ -192,7 +192,7 @@ Describe 'Invoke-SqlDscScalarQuery' -Tag 'Public' { Context 'When an exception is thrown' { BeforeAll { - $mockConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.ServerConnection' + $mockConnectionContext = New-Object -TypeName 'Microsoft.SqlServer.Management.Common.ServerConnection' $mockConnectionContext.StatementTimeout = 100 $mockConnectionContext | Add-Member -MemberType 'ScriptMethod' -Name 'ExecuteScalar' -Value { $script:mockMethodExecuteScalarCallCount += 1 diff --git a/tests/Unit/SqlServerDsc.Common/Public/Connect-Sql.Tests.ps1 b/tests/Unit/SqlServerDsc.Common/Public/Connect-Sql.Tests.ps1 index a834ade470..0fe0a3836b 100644 --- a/tests/Unit/SqlServerDsc.Common/Public/Connect-Sql.Tests.ps1 +++ b/tests/Unit/SqlServerDsc.Common/Public/Connect-Sql.Tests.ps1 @@ -85,7 +85,7 @@ AfterAll { Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { BeforeEach { - $mockNewObject_MicrosoftDatabaseEngine = { + $mockNewObject_MicrosoftServerConnection = { <# $ArgumentList[0] will contain the ServiceInstance when calling mock New-Object. But since the mock New-Object will also be called without arguments, we first @@ -96,6 +96,44 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { $serverInstance = $ArgumentList[0] } + return New-Object -TypeName Object | + Add-Member -MemberType NoteProperty -Name ServerInstance -Value $serverInstance -PassThru | + Add-Member -MemberType NoteProperty -Name LoginSecure -Value $true -PassThru | + Add-Member -MemberType NoteProperty -Name Login -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name SecurePassword -Value $null -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectAsUser -Value $false -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectAsUserPassword -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectAsUserName -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name StatementTimeout -Value 600 -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectTimeout -Value 600 -PassThru | + Add-Member -MemberType NoteProperty -Name EncryptConnection -Value $false -PassThru | + Add-Member -MemberType NoteProperty -Name ApplicationName -Value 'SqlServerDsc' -PassThru | + Add-Member -MemberType ScriptMethod -Name Disconnect -Value { + return $true + } -PassThru | + Add-Member -MemberType ScriptMethod -Name Connect -Value { + if ($mockExpectedDatabaseEngineInstance -eq 'MSSQLSERVER') + { + $mockExpectedServiceInstance = $mockExpectedDatabaseEngineServer + } + else + { + $mockExpectedServiceInstance = "$mockExpectedDatabaseEngineServer\$mockExpectedDatabaseEngineInstance" + } + + if ($this.ServerInstance -ne $mockExpectedServiceInstance) + { + throw ("Mock method Connect() was expecting ServerInstance to be '{0}', but was '{1}'." -f $mockExpectedServiceInstance, $this.serverInstance ) + } + + if ($mockThrowInvalidOperation) + { + throw 'Unable to connect.' + } + } -PassThru -Force + } + + $mockNewObject_MicrosoftDatabaseEngine = { return New-Object -TypeName Object | Add-Member -MemberType ScriptProperty -Name Status -Value { if ($mockExpectedDatabaseEngineInstance -eq 'MSSQLSERVER') @@ -116,49 +154,17 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { return $null } } -PassThru | - Add-Member -MemberType NoteProperty -Name ConnectionContext -Value ( - New-Object -TypeName Object | - Add-Member -MemberType NoteProperty -Name ServerInstance -Value $serverInstance -PassThru | - Add-Member -MemberType NoteProperty -Name LoginSecure -Value $true -PassThru | - Add-Member -MemberType NoteProperty -Name Login -Value '' -PassThru | - Add-Member -MemberType NoteProperty -Name SecurePassword -Value $null -PassThru | - Add-Member -MemberType NoteProperty -Name ConnectAsUser -Value $false -PassThru | - Add-Member -MemberType NoteProperty -Name ConnectAsUserPassword -Value '' -PassThru | - Add-Member -MemberType NoteProperty -Name ConnectAsUserName -Value '' -PassThru | - Add-Member -MemberType NoteProperty -Name StatementTimeout -Value 600 -PassThru | - Add-Member -MemberType NoteProperty -Name ConnectTimeout -Value 600 -PassThru | - Add-Member -MemberType NoteProperty -Name EncryptConnection -Value $false -PassThru | - Add-Member -MemberType NoteProperty -Name ApplicationName -Value 'SqlServerDsc' -PassThru | - Add-Member -MemberType ScriptMethod -Name Disconnect -Value { - return $true - } -PassThru | - Add-Member -MemberType ScriptMethod -Name Connect -Value { - if ($mockExpectedDatabaseEngineInstance -eq 'MSSQLSERVER') - { - $mockExpectedServiceInstance = $mockExpectedDatabaseEngineServer - } - else - { - $mockExpectedServiceInstance = "$mockExpectedDatabaseEngineServer\$mockExpectedDatabaseEngineInstance" - } - - if ($this.serverInstance -ne $mockExpectedServiceInstance) - { - throw ("Mock method Connect() was expecting ServerInstance to be '{0}', but was '{1}'." -f $mockExpectedServiceInstance, $this.serverInstance ) - } - - if ($mockThrowInvalidOperation) - { - throw 'Unable to connect.' - } - } -PassThru -Force - ) -PassThru -Force + Add-Member -MemberType NoteProperty -Name ConnectionContext -Value $ArgumentList[0] -PassThru -Force } $mockNewObject_MicrosoftDatabaseEngine_ParameterFilter = { $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Server' } + $mockNewObject_MicrosoftServerConnection_ParameterFilter = { + $TypeName -eq 'Microsoft.SqlServer.Management.Common.ServerConnection' + } + $mockSqlCredentialUserName = 'TestUserName12345' $mockSqlCredentialPassword = 'StrongOne7.' $mockSqlCredentialSecurePassword = ConvertTo-SecureString -String $mockSqlCredentialPassword -AsPlainText -Force @@ -186,6 +192,9 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { Mock -CommandName New-Object ` -MockWith $mockNewObject_MicrosoftDatabaseEngine ` -ParameterFilter $mockNewObject_MicrosoftDatabaseEngine_ParameterFilter + + Mock -CommandName New-Object -MockWith $mockNewObject_MicrosoftServerConnection ` + -ParameterFilter $mockNewObject_MicrosoftServerConnection_ParameterFilter } It 'Should return the correct service instance' { @@ -206,6 +215,9 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { Mock -CommandName New-Object ` -MockWith $mockNewObject_MicrosoftDatabaseEngine ` -ParameterFilter $mockNewObject_MicrosoftDatabaseEngine_ParameterFilter + + Mock -CommandName New-Object -MockWith $mockNewObject_MicrosoftServerConnection ` + -ParameterFilter $mockNewObject_MicrosoftServerConnection_ParameterFilter } It 'Should return the correct service instance' { @@ -229,6 +241,9 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { Mock -CommandName New-Object ` -MockWith $mockNewObject_MicrosoftDatabaseEngine ` -ParameterFilter $mockNewObject_MicrosoftDatabaseEngine_ParameterFilter + + Mock -CommandName New-Object -MockWith $mockNewObject_MicrosoftServerConnection ` + -ParameterFilter $mockNewObject_MicrosoftServerConnection_ParameterFilter } It 'Should return the correct service instance' { @@ -249,6 +264,9 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { Mock -CommandName New-Object ` -MockWith $mockNewObject_MicrosoftDatabaseEngine ` -ParameterFilter $mockNewObject_MicrosoftDatabaseEngine_ParameterFilter + + Mock -CommandName New-Object -MockWith $mockNewObject_MicrosoftServerConnection ` + -ParameterFilter $mockNewObject_MicrosoftServerConnection_ParameterFilter } It 'Should return the correct service instance' { @@ -272,6 +290,9 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { Mock -CommandName New-Object ` -MockWith $mockNewObject_MicrosoftDatabaseEngine ` -ParameterFilter $mockNewObject_MicrosoftDatabaseEngine_ParameterFilter + + Mock -CommandName New-Object -MockWith $mockNewObject_MicrosoftServerConnection ` + -ParameterFilter $mockNewObject_MicrosoftServerConnection_ParameterFilter } It 'Should return the correct service instance' { @@ -291,6 +312,9 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { Mock -CommandName New-Object ` -MockWith $mockNewObject_MicrosoftDatabaseEngine ` -ParameterFilter $mockNewObject_MicrosoftDatabaseEngine_ParameterFilter + + Mock -CommandName New-Object -MockWith $mockNewObject_MicrosoftServerConnection ` + -ParameterFilter $mockNewObject_MicrosoftServerConnection_ParameterFilter } Context 'When using the default login type' { @@ -375,6 +399,9 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { Mock -CommandName New-Object ` -MockWith $mockNewObject_MicrosoftDatabaseEngine ` -ParameterFilter $mockNewObject_MicrosoftDatabaseEngine_ParameterFilter + + Mock -CommandName New-Object -MockWith $mockNewObject_MicrosoftServerConnection ` + -ParameterFilter $mockNewObject_MicrosoftServerConnection_ParameterFilter } # Skipping on Linux and macOS because they do not support Windows Authentication. @@ -398,17 +425,40 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { Add-Member -MemberType ScriptProperty -Name Status -Value { return 'Online' } -PassThru | - Add-Member -MemberType NoteProperty -Name ConnectionContext -Value ( - New-Object -TypeName Object | - Add-Member -MemberType NoteProperty -Name ServerInstance -Value '' -PassThru | - Add-Member -MemberType NoteProperty -Name LoginSecure -Value $true -PassThru | - Add-Member -MemberType NoteProperty -Name StatementTimeout -Value 600 -PassThru | - Add-Member -MemberType NoteProperty -Name ConnectTimeout -Value 600 -PassThru | - Add-Member -MemberType NoteProperty -Name ApplicationName -Value 'SqlServerDsc' -PassThru | - Add-Member -MemberType ScriptMethod -Name Disconnect -Value { return $true } -PassThru | - Add-Member -MemberType ScriptMethod -Name Connect -Value { } -PassThru -Force - ) -PassThru -Force + Add-Member -MemberType NoteProperty -Name ConnectionContext -Value $ArgumentList[0] -PassThru -Force + } + + $mockNewObject_MicrosoftServerConnection = { + <# + $ArgumentList[0] will contain the ServiceInstance when calling mock New-Object. + But since the mock New-Object will also be called without arguments, we first + have to evaluate if $ArgumentList contains values. + #> + if ( $ArgumentList.Count -gt 0) + { + $serverInstance = $ArgumentList[0] + } + + return New-Object -TypeName Object | + Add-Member -MemberType NoteProperty -Name ServerInstance -Value $serverInstance -PassThru | + Add-Member -MemberType NoteProperty -Name LoginSecure -Value $true -PassThru | + Add-Member -MemberType NoteProperty -Name Login -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name SecurePassword -Value $null -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectAsUser -Value $false -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectAsUserPassword -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectAsUserName -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name StatementTimeout -Value 600 -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectTimeout -Value 600 -PassThru | + Add-Member -MemberType NoteProperty -Name EncryptConnection -Value $false -PassThru | + Add-Member -MemberType NoteProperty -Name ApplicationName -Value 'SqlServerDsc' -PassThru | + Add-Member -MemberType ScriptMethod -Name Disconnect -Value { + return $true + } -PassThru | + Add-Member -MemberType ScriptMethod -Name Connect -Value {} -PassThru -Force } + + Mock -CommandName New-Object -MockWith $mockNewObject_MicrosoftServerConnection ` + -ParameterFilter $mockNewObject_MicrosoftServerConnection_ParameterFilter } # Skipping on Linux and macOS because they do not support Windows Authentication. @@ -435,17 +485,40 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { Add-Member -MemberType ScriptProperty -Name Status -Value { return 'Online' } -PassThru | - Add-Member -MemberType NoteProperty -Name ConnectionContext -Value ( - New-Object -TypeName Object | - Add-Member -MemberType NoteProperty -Name ServerInstance -Value '' -PassThru | - Add-Member -MemberType NoteProperty -Name LoginSecure -Value $true -PassThru | - Add-Member -MemberType NoteProperty -Name StatementTimeout -Value 600 -PassThru | - Add-Member -MemberType NoteProperty -Name ConnectTimeout -Value 600 -PassThru | - Add-Member -MemberType NoteProperty -Name ApplicationName -Value 'SqlServerDsc' -PassThru | - Add-Member -MemberType ScriptMethod -Name Disconnect -Value { return $true } -PassThru | - Add-Member -MemberType ScriptMethod -Name Connect -Value { } -PassThru -Force - ) -PassThru -Force + Add-Member -MemberType NoteProperty -Name ConnectionContext -Value $ArgumentList[0] -PassThru -Force } + + $mockNewObject_MicrosoftServerConnection = { + <# + $ArgumentList[0] will contain the ServiceInstance when calling mock New-Object. + But since the mock New-Object will also be called without arguments, we first + have to evaluate if $ArgumentList contains values. + #> + if ( $ArgumentList.Count -gt 0) + { + $serverInstance = $ArgumentList[0] + } + + return New-Object -TypeName Object | + Add-Member -MemberType NoteProperty -Name ServerInstance -Value $serverInstance -PassThru | + Add-Member -MemberType NoteProperty -Name LoginSecure -Value $true -PassThru | + Add-Member -MemberType NoteProperty -Name Login -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name SecurePassword -Value $null -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectAsUser -Value $false -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectAsUserPassword -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectAsUserName -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name StatementTimeout -Value 600 -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectTimeout -Value 600 -PassThru | + Add-Member -MemberType NoteProperty -Name EncryptConnection -Value $false -PassThru | + Add-Member -MemberType NoteProperty -Name ApplicationName -Value 'SqlServerDsc' -PassThru | + Add-Member -MemberType ScriptMethod -Name Disconnect -Value { + return $true + } -PassThru | + Add-Member -MemberType ScriptMethod -Name Connect -Value {} -PassThru -Force + } + + Mock -CommandName New-Object -MockWith $mockNewObject_MicrosoftServerConnection ` + -ParameterFilter $mockNewObject_MicrosoftServerConnection_ParameterFilter } # Skipping on Linux and macOS because they do not support Windows Authentication. @@ -472,17 +545,40 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { Add-Member -MemberType ScriptProperty -Name Status -Value { return 'Online' } -PassThru | - Add-Member -MemberType NoteProperty -Name ConnectionContext -Value ( - New-Object -TypeName Object | - Add-Member -MemberType NoteProperty -Name ServerInstance -Value '' -PassThru | - Add-Member -MemberType NoteProperty -Name LoginSecure -Value $true -PassThru | - Add-Member -MemberType NoteProperty -Name StatementTimeout -Value 600 -PassThru | - Add-Member -MemberType NoteProperty -Name ConnectTimeout -Value 600 -PassThru | - Add-Member -MemberType NoteProperty -Name ApplicationName -Value 'SqlServerDsc' -PassThru | - Add-Member -MemberType ScriptMethod -Name Disconnect -Value { return $true } -PassThru | - Add-Member -MemberType ScriptMethod -Name Connect -Value { } -PassThru -Force - ) -PassThru -Force + Add-Member -MemberType NoteProperty -Name ConnectionContext -Value $ArgumentList[0] -PassThru -Force + } + + $mockNewObject_MicrosoftServerConnection = { + <# + $ArgumentList[0] will contain the ServiceInstance when calling mock New-Object. + But since the mock New-Object will also be called without arguments, we first + have to evaluate if $ArgumentList contains values. + #> + if ( $ArgumentList.Count -gt 0) + { + $serverInstance = $ArgumentList[0] + } + + return New-Object -TypeName Object | + Add-Member -MemberType NoteProperty -Name ServerInstance -Value $serverInstance -PassThru | + Add-Member -MemberType NoteProperty -Name LoginSecure -Value $true -PassThru | + Add-Member -MemberType NoteProperty -Name Login -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name SecurePassword -Value $null -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectAsUser -Value $false -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectAsUserPassword -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectAsUserName -Value '' -PassThru | + Add-Member -MemberType NoteProperty -Name StatementTimeout -Value 600 -PassThru | + Add-Member -MemberType NoteProperty -Name ConnectTimeout -Value 600 -PassThru | + Add-Member -MemberType NoteProperty -Name EncryptConnection -Value $false -PassThru | + Add-Member -MemberType NoteProperty -Name ApplicationName -Value 'SqlServerDsc' -PassThru | + Add-Member -MemberType ScriptMethod -Name Disconnect -Value { + return $true + } -PassThru | + Add-Member -MemberType ScriptMethod -Name Connect -Value {} -PassThru -Force } + + Mock -CommandName New-Object -MockWith $mockNewObject_MicrosoftServerConnection ` + -ParameterFilter $mockNewObject_MicrosoftServerConnection_ParameterFilter } # Skipping on Linux and macOS because they do not support Windows Authentication. @@ -580,9 +676,7 @@ Describe 'SqlServerDsc.Common\Connect-SQL' -Tag 'ConnectSql' { It 'Should not throw an exception' { $null = Connect-SQL -ServerName 'localhost' -SetupCredential $mockSqlCredential -LoginType 'SqlLogin' -ErrorAction 'SilentlyContinue' - Should -Invoke -CommandName New-Object -ParameterFilter { - $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Server' - } -Exactly -Times 1 -Scope It + Should -Invoke -CommandName New-Object -ParameterFilter $mockNewObject_MicrosoftDatabaseEngine_ParameterFilter -Exactly -Times 1 -Scope It } } } diff --git a/tests/Unit/SqlServerDsc.Common/Public/Test-ImpersonatePermissions.Tests.ps1 b/tests/Unit/SqlServerDsc.Common/Public/Test-ImpersonatePermissions.Tests.ps1 index e19b0c6e79..cf4b1812a5 100644 --- a/tests/Unit/SqlServerDsc.Common/Public/Test-ImpersonatePermissions.Tests.ps1 +++ b/tests/Unit/SqlServerDsc.Common/Public/Test-ImpersonatePermissions.Tests.ps1 @@ -101,7 +101,7 @@ Describe 'SqlServerDsc.Common\Test-ImpersonatePermissions' -Tag 'TestImpersonate $Permissions -eq @('CONTROL') } - $mockConnectionContextObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ServerConnection + $mockConnectionContextObject = New-Object -TypeName Microsoft.SqlServer.Management.Common.ServerConnection $mockConnectionContextObject.TrueLogin = 'Login1' $mockServerObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server diff --git a/tests/Unit/Stubs/SMO.cs b/tests/Unit/Stubs/SMO.cs index b60867d1de..a29567d860 100644 --- a/tests/Unit/Stubs/SMO.cs +++ b/tests/Unit/Stubs/SMO.cs @@ -487,7 +487,7 @@ public DatabasePermissionInfo( Microsoft.SqlServer.Management.Smo.DatabasePermis public class Server { public AvailabilityGroupCollection AvailabilityGroups = new AvailabilityGroupCollection(); - public ServerConnection ConnectionContext; + public Microsoft.SqlServer.Management.Common.ServerConnection ConnectionContext; public string ComputerNamePhysicalNetBIOS; public DatabaseCollection Databases = new DatabaseCollection(); public string DisplayName; @@ -515,6 +515,12 @@ public Server(string name) this.Name = name; } + public Server(Microsoft.SqlServer.Management.Common.ServerConnection serverConnection) + { + this.ConnectionContext = serverConnection; + this.Name = serverConnection.ServerInstance; + } + public Server Clone() { return new Server() @@ -540,6 +546,8 @@ public Server Clone() }; } + public void Refresh() {} + public Microsoft.SqlServer.Management.Smo.ServerPermissionInfo[] EnumServerPermissions( string principal, Microsoft.SqlServer.Management.Smo.ServerPermissionSet permissionSetQuery ) { Microsoft.SqlServer.Management.Smo.ServerPermissionInfo[] permissionInfo = null; @@ -1362,26 +1370,6 @@ public void Create() {} } - // TypeName: Microsoft.SqlServer.Management.Common.ServerConnection - // Used by: - // SqlAGDatabase - // Invoke-SqlDscScalarQuery - public class ServerConnection - { - public string TrueLogin; - public int StatementTimeout; - - public void Create() - {} - - // Method: ExecuteScalar - // Used for testing scalar query execution in Invoke-SqlDscScalarQuery - public object ExecuteScalar(string query) - { - return null; - } - } - // TypeName: Microsoft.SqlServer.Management.Smo.AvailabilityDatabase // Used by: // SqlAGDatabase @@ -2796,4 +2784,42 @@ public enum DatabaseEngineType : int } #endregion + + // TypeName: Microsoft.SqlServer.Management.Common.ServerConnection + // Used by: + // SqlAGDatabase + // Invoke-SqlDscScalarQuery + public class ServerConnection + { + public string ApplicationName { get; set; } + public bool ConnectAsUser { get; set; } + public string ConnectAsUserName { get; set; } + public string ConnectAsUserPassword { get; set; } + public int ConnectTimeout { get; set; } + public bool EncryptConnection { get; set; } + public string Login { get; set; } + public bool LoginSecure { get; set; } + public System.Security.SecureString SecurePassword { get; set; } + public string ServerInstance { get; set; } + public int StatementTimeout { get; set; } + public string TrueLogin { get; set; } + + public ServerConnection(){} + + public ServerConnection(string serverInstance) + { + this.ServerInstance = serverInstance; + } + + public void Connect() {} + + public void Disconnect() {} + + // Method: ExecuteScalar + // Used for testing scalar query execution in Invoke-SqlDscScalarQuery + public object ExecuteScalar(string query) + { + return null; + } + } }