From 291b7a20716a645885d32164ebf59f9270779e82 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Wed, 4 Jul 2018 17:16:16 +0200 Subject: [PATCH] Refactor SqlServerNetwork to not load assembly from GAC (issue #1151) --- .../MSFT_SqlServerNetwork.psm1 | 164 ++++++++---------- SqlServerDscHelper.psm1 | 145 ---------------- ...SFT_SqlServerNetwork.Integration.Tests.ps1 | 104 +++++++++++ .../MSFT_SqlServerNetwork.config.ps1 | 42 +++++ Tests/Unit/MSFT_SqlServerNetwork.Tests.ps1 | 20 +-- Tests/Unit/SqlServerDSCHelper.Tests.ps1 | 103 ----------- en-US/SqlServerDscHelper.strings.psd1 | 4 - sv-SE/SqlServerDscHelper.strings.psd1 | 6 +- 8 files changed, 227 insertions(+), 361 deletions(-) create mode 100644 Tests/Integration/MSFT_SqlServerNetwork.Integration.Tests.ps1 create mode 100644 Tests/Integration/MSFT_SqlServerNetwork.config.ps1 diff --git a/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.psm1 b/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.psm1 index 0ce468776..b2096f768 100644 --- a/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.psm1 +++ b/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.psm1 @@ -22,6 +22,11 @@ function Get-TargetResource [OutputType([System.Collections.Hashtable])] param ( + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName = $env:COMPUTERNAME, + [Parameter(Mandatory = $true)] [System.String] $InstanceName, @@ -33,31 +38,24 @@ function Get-TargetResource $ProtocolName ) - try - { - $applicationDomainObject = Register-SqlWmiManagement -SQLInstanceName $InstanceName - - $managedComputerObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer + $sql = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName - Write-Verbose -Message ($script:localizedData.GetNetworkProtocol -f $ProtocolName, $InstanceName) - $tcp = $managedComputerObject.ServerInstances[$InstanceName].ServerProtocols[$ProtocolName] + $managedComputerObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer - Write-Verbose -Message $script:localizedData.ReadingNetworkProperties - $returnValue = @{ - InstanceName = $InstanceName - ProtocolName = $ProtocolName - IsEnabled = $tcp.IsEnabled - TcpDynamicPort = ($tcp.IPAddresses['IPAll'].IPAddressProperties['TcpDynamicPorts'].Value -ge 0) - TcpPort = $tcp.IPAddresses['IPAll'].IPAddressProperties['TcpPort'].Value - } + Write-Verbose -Message ($script:localizedData.GetNetworkProtocol -f $ProtocolName, $InstanceName) + $tcp = $managedComputerObject.ServerInstances[$InstanceName].ServerProtocols[$ProtocolName] - $returnValue.Keys | ForEach-Object { - Write-Verbose -Message "$_ = $($returnValue[$_])" - } + Write-Verbose -Message $script:localizedData.ReadingNetworkProperties + $returnValue = @{ + InstanceName = $InstanceName + ProtocolName = $ProtocolName + IsEnabled = $tcp.IsEnabled + TcpDynamicPort = ($tcp.IPAddresses['IPAll'].IPAddressProperties['TcpDynamicPorts'].Value -ge 0) + TcpPort = $tcp.IPAddresses['IPAll'].IPAddressProperties['TcpPort'].Value } - finally - { - Unregister-SqlAssemblies -ApplicationDomain $applicationDomainObject + + $returnValue.Keys | ForEach-Object { + Write-Verbose -Message "$_ = $($returnValue[$_])" } return $returnValue @@ -145,90 +143,82 @@ function Set-TargetResource $getTargetResourceResult = Get-TargetResource -InstanceName $InstanceName -ProtocolName $ProtocolName - try - { - $applicationDomainObject = Register-SqlWmiManagement -SQLInstanceName $InstanceName - - $desiredState = @{ - InstanceName = $InstanceName - ProtocolName = $ProtocolName - IsEnabled = $IsEnabled - TcpDynamicPort = $TcpDynamicPort - TcpPort = $TcpPort - } - - $isRestartNeeded = $false - - $managedComputerObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer - - Write-Verbose -Message ($script:localizedData.GetNetworkProtocol -f $ProtocolName, $InstanceName) - $tcp = $managedComputerObject.ServerInstances[$InstanceName].ServerProtocols[$ProtocolName] + $desiredState = @{ + InstanceName = $InstanceName + ProtocolName = $ProtocolName + IsEnabled = $IsEnabled + TcpDynamicPort = $TcpDynamicPort + TcpPort = $TcpPort + } - Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'IsEnabled') - if ($desiredState.IsEnabled -ine $getTargetResourceResult.IsEnabled) - { - Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'IsEnabled', $getTargetResourceResult.IsEnabled, $desiredState.IsEnabled) - $tcp.IsEnabled = $desiredState.IsEnabled - $tcp.Alter() + $isRestartNeeded = $false - $isRestartNeeded = $true - } + # Get-TargetResource makes the necessary calls so the type ManagedComputer is available. + $managedComputerObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer - Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'TcpDynamicPort') - if ($desiredState.TcpDynamicPort -ne $getTargetResourceResult.TcpDynamicPort) - { - # Translates the current and desired state to a string for display - $dynamicPortDisplayValueTable = @{ - $true = 'enabled' - $false = 'disabled' - } + Write-Verbose -Message ($script:localizedData.GetNetworkProtocol -f $ProtocolName, $InstanceName) + $tcp = $managedComputerObject.ServerInstances[$InstanceName].ServerProtocols[$ProtocolName] - # Translates the desired state to a valid value - $desiredDynamicPortValue = @{ - $true = '0' - $false = '' - } + Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'IsEnabled') + if ($desiredState.IsEnabled -ine $getTargetResourceResult.IsEnabled) + { + Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'IsEnabled', $getTargetResourceResult.IsEnabled, $desiredState.IsEnabled) + $tcp.IsEnabled = $desiredState.IsEnabled + $tcp.Alter() - $fromTcpDynamicPortDisplayValue = $dynamicPortDisplayValueTable[$getTargetResourceResult.TcpDynamicPort] - $toTcpDynamicPortDisplayValue = $dynamicPortDisplayValueTable[$desiredState.TcpDynamicPort] + $isRestartNeeded = $true + } - Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'TcpDynamicPorts', $fromTcpDynamicPortDisplayValue, $toTcpDynamicPortDisplayValue) - $tcp.IPAddresses['IPAll'].IPAddressProperties['TcpDynamicPorts'].Value = $desiredDynamicPortValue[$desiredState.TcpDynamicPort] - $tcp.Alter() + Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'TcpDynamicPort') + if ($desiredState.TcpDynamicPort -ne $getTargetResourceResult.TcpDynamicPort) + { + # Translates the current and desired state to a string for display + $dynamicPortDisplayValueTable = @{ + $true = 'enabled' + $false = 'disabled' + } - $isRestartNeeded = $true + # Translates the desired state to a valid value + $desiredDynamicPortValue = @{ + $true = '0' + $false = '' } - Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'TcpPort') - if ($desiredState.TcpPort -ine $getTargetResourceResult.TcpPort) - { - $fromTcpPort = $getTargetResourceResult.TcpPort - if ($fromTcpPort -eq '') - { - $fromTcpPort = 'none' - } + $fromTcpDynamicPortDisplayValue = $dynamicPortDisplayValueTable[$getTargetResourceResult.TcpDynamicPort] + $toTcpDynamicPortDisplayValue = $dynamicPortDisplayValueTable[$desiredState.TcpDynamicPort] - $toTcpPort = $desiredState.TcpPort - if ($toTcpPort -eq '') - { - $toTcpPort = 'none' - } + Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'TcpDynamicPorts', $fromTcpDynamicPortDisplayValue, $toTcpDynamicPortDisplayValue) + $tcp.IPAddresses['IPAll'].IPAddressProperties['TcpDynamicPorts'].Value = $desiredDynamicPortValue[$desiredState.TcpDynamicPort] + $tcp.Alter() - Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'TcpPort', $fromTcpPort, $toTcpPort) - $tcp.IPAddresses['IPAll'].IPAddressProperties['TcpPort'].Value = $desiredState.TcpPort - $tcp.Alter() + $isRestartNeeded = $true + } - $isRestartNeeded = $true + Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'TcpPort') + if ($desiredState.TcpPort -ine $getTargetResourceResult.TcpPort) + { + $fromTcpPort = $getTargetResourceResult.TcpPort + if ($fromTcpPort -eq '') + { + $fromTcpPort = 'none' } - if ($RestartService -and $isRestartNeeded) + $toTcpPort = $desiredState.TcpPort + if ($toTcpPort -eq '') { - Restart-SqlService -SQLServer $ServerName -SQLInstanceName $InstanceName -Timeout $RestartTimeout + $toTcpPort = 'none' } + + Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'TcpPort', $fromTcpPort, $toTcpPort) + $tcp.IPAddresses['IPAll'].IPAddressProperties['TcpPort'].Value = $desiredState.TcpPort + $tcp.Alter() + + $isRestartNeeded = $true } - finally + + if ($RestartService -and $isRestartNeeded) { - Unregister-SqlAssemblies -ApplicationDomain $applicationDomainObject + Restart-SqlService -SQLServer $ServerName -SQLInstanceName $InstanceName -Timeout $RestartTimeout } } diff --git a/SqlServerDscHelper.psm1 b/SqlServerDscHelper.psm1 index e79e5ca10..65c82b69f 100644 --- a/SqlServerDscHelper.psm1 +++ b/SqlServerDscHelper.psm1 @@ -179,151 +179,6 @@ function Connect-SQLAnalysis return $analysisServicesObject } -<# - .SYNOPSIS - Creates a new application domain and loads the assemblies Microsoft.SqlServer.Smo - for the correct SQL Server major version. - - An isolated application domain is used to load version specific assemblies, this needed - if there is multiple versions of SQL server in the same configuration. So that a newer - version of SQL is not using an older version of the assembly, or vice verse. - - This should be unloaded using the helper function Unregister-SqlAssemblies or - using [System.AppDomain]::Unload($applicationDomainObject). - - .PARAMETER SQLInstanceName - String containing the SQL Server Database Engine instance name to get the major SQL version from. - - .PARAMETER ApplicationDomain - An optional System.AppDomain object to load the assembly into. - - .OUTPUTS - System.AppDomain. Returns the application domain object with SQL SMO loaded. -#> -function Register-SqlSmo -{ - [CmdletBinding()] - [OutputType([System.AppDomain])] - param - ( - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String] - $SQLInstanceName, - - [Parameter()] - [ValidateNotNullOrEmpty()] - [System.AppDomain] - $ApplicationDomain - ) - - $sqlMajorVersion = Get-SqlInstanceMajorVersion -SQLInstanceName $SQLInstanceName - - Write-Verbose -Message ($script:localizedData.SqlMajorVersion -f $sqlMajorVersion) -Verbose - - if ( -not $ApplicationDomain ) - { - $applicationDomainName = $MyInvocation.MyCommand.ModuleName - Write-Verbose -Message ($script:localizedData.CreatingApplicationDomain -f $applicationDomainName) -Verbose - $applicationDomainObject = [System.AppDomain]::CreateDomain($applicationDomainName) - } - else - { - Write-Verbose -Message ($script:localizedData.ReusingApplicationDomain -f $ApplicationDomain.FriendlyName) -Verbose - $applicationDomainObject = $ApplicationDomain - } - - $sqlSmoAssemblyName = "Microsoft.SqlServer.Smo, Version=$sqlMajorVersion.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" - Write-Verbose -Message ($script:localizedData.LoadingAssembly -f $sqlSmoAssemblyName) -Verbose - $applicationDomainObject.Load($sqlSmoAssemblyName) | Out-Null - - return $applicationDomainObject -} - -<# - .SYNOPSIS - Creates a new application domain and loads the assemblies Microsoft.SqlServer.Smo and - Microsoft.SqlServer.SqlWmiManagement for the correct SQL Server major version. - - An isolated application domain is used to load version specific assemblies, this needed - if there is multiple versions of SQL server in the same configuration. So that a newer - version of SQL is not using an older version of the assembly, or vice verse. - - This should be unloaded using the helper function Unregister-SqlAssemblies or - using [System.AppDomain]::Unload($applicationDomainObject) preferably in a finally block. - - .PARAMETER SQLInstanceName - String containing the SQL Server Database Engine instance name to get the major SQL version from. - - .PARAMETER ApplicationDomain - An optional System.AppDomain object to load the assembly into. - - .OUTPUTS - System.AppDomain. Returns the application domain object with SQL WMI Management loaded. -#> -function Register-SqlWmiManagement -{ - [CmdletBinding()] - [OutputType([System.AppDomain])] - param - ( - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String] - $SQLInstanceName, - - [Parameter()] - [ValidateNotNull()] - [System.AppDomain] - $ApplicationDomain - ) - - $sqlMajorVersion = Get-SqlInstanceMajorVersion -SQLInstanceName $SQLInstanceName - Write-Verbose -Message ($script:localizedData.SqlMajorVersion -f $sqlMajorVersion) -Verbose - - <# - Must register Microsoft.SqlServer.Smo first because that is a - dependency of Microsoft.SqlServer.SqlWmiManagement. - #> - if (-not $ApplicationDomain) - { - $applicationDomainObject = Register-SqlSmo -SQLInstanceName $SQLInstanceName - } - # Returns zero (0) objects if the assembly is not found - elseif (-not ($ApplicationDomain.GetAssemblies().FullName -match 'Microsoft.SqlServer.Smo')) - { - $applicationDomainObject = Register-SqlSmo -SQLInstanceName $SQLInstanceName -ApplicationDomain $ApplicationDomain - } - - $sqlSqlWmiManagementAssemblyName = "Microsoft.SqlServer.SqlWmiManagement, Version=$sqlMajorVersion.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" - Write-Verbose -Message ($script:localizedData.LoadingAssembly -f $sqlSqlWmiManagementAssemblyName) -Verbose - $applicationDomainObject.Load($sqlSqlWmiManagementAssemblyName) | Out-Null - - return $applicationDomainObject -} - -<# - .SYNOPSIS - Unloads all assemblies in an application domain. It unloads the application domain. - - .PARAMETER ApplicationDomain - System.AppDomain object containing the SQL assemblies to unload. -#> -function Unregister-SqlAssemblies -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [ValidateNotNull()] - [System.AppDomain] - $ApplicationDomain - ) - - Write-Verbose -Message ($script:localizedData.UnloadingApplicationDomain -f $ApplicationDomain.FriendlyName) -Verbose - [System.AppDomain]::Unload($ApplicationDomain) -} - <# .SYNOPSIS Returns the major SQL version for the specific instance. diff --git a/Tests/Integration/MSFT_SqlServerNetwork.Integration.Tests.ps1 b/Tests/Integration/MSFT_SqlServerNetwork.Integration.Tests.ps1 new file mode 100644 index 000000000..9dbbb7a77 --- /dev/null +++ b/Tests/Integration/MSFT_SqlServerNetwork.Integration.Tests.ps1 @@ -0,0 +1,104 @@ +# This is used to make sure the integration test run in the correct order. +[Microsoft.DscResourceKit.IntegrationTest(OrderNumber = 2)] +param() + +$script:DSCModuleName = 'SqlServerDsc' +$script:DSCResourceFriendlyName = 'SqlServerDatabaseMail' +$script:DSCResourceName = "MSFT_$($script:DSCResourceFriendlyName)" + +if (-not $env:APPVEYOR -eq $true) +{ + Write-Warning -Message ('Integration test for {0} will be skipped unless $env:APPVEYOR equals $true' -f $script:DSCResourceName) + return +} + +#region HEADER +# Integration Test Template Version: 1.1.2 +[System.String] $script:moduleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) +if ( (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` + (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) +{ + & git @('clone', 'https://github.com/PowerShell/DscResource.Tests.git', (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests')) +} + +Import-Module -Name (Join-Path -Path $script:moduleRoot -ChildPath (Join-Path -Path 'DSCResource.Tests' -ChildPath 'TestHelper.psm1')) -Force +$TestEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:DSCModuleName ` + -DSCResourceName $script:DSCResourceName ` + -TestType Integration + +#endregion + +$mockSqlInstallAccountPassword = ConvertTo-SecureString -String 'P@ssw0rd1' -AsPlainText -Force +$mockSqlInstallAccountUserName = "$env:COMPUTERNAME\SqlInstall" +$mockSqlInstallCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $mockSqlInstallAccountUserName, $mockSqlInstallAccountPassword + +try +{ + $configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:DSCResourceName).config.ps1" + . $configFile + + $mockProtocolName = $ConfigurationData.AllNodes.ProtocolName + $mockIsEnabled = $ConfigurationData.AllNodes.IsEnabled + $mockTcpDynamicPort = $ConfigurationData.AllNodes.TcpDynamicPort + + Describe "$($script:DSCResourceName)_Integration" { + BeforeAll { + $resourceId = "[$($script:DSCResourceFriendlyName)]Integration_Test" + } + + $configurationName = "$($script:DSCResourceName)_SetTcpDynamicPort_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + SqlInstallCredential = $mockSqlInstallCredential + OutputPath = $TestDrive + # The variable $ConfigurationData was dot-sourced above. + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName + } | Where-Object -FilterScript { + $_.ResourceId -eq $resourceId + } + + $resourceCurrentState.IsEnabled | Should -Be $mockIsEnabled + $resourceCurrentState.ProtocolName | Should -Be $mockProtocolName + $resourceCurrentState.TcpDynamicPort | Should -Be $mockTcpDynamicPort + } + } + } +} +finally +{ + #region FOOTER + + Restore-TestEnvironment -TestEnvironment $TestEnvironment + + #endregion +} diff --git a/Tests/Integration/MSFT_SqlServerNetwork.config.ps1 b/Tests/Integration/MSFT_SqlServerNetwork.config.ps1 new file mode 100644 index 000000000..593f85144 --- /dev/null +++ b/Tests/Integration/MSFT_SqlServerNetwork.config.ps1 @@ -0,0 +1,42 @@ +$ConfigurationData = @{ + AllNodes = @( + @{ + NodeName = 'localhost' + ServerName = $env:COMPUTERNAME + InstanceName = 'DSCSQL2016' + + PSDscAllowPlainTextPassword = $true + + ProtocolName = 'Tcp' + IsEnabled = $true + TcpDynamicPort = $true + RestartService = $true + } + ) +} + +Configuration MSFT_SqlServerNetwork_SetTcpDynamicPort_Config +{ + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCredential] + $SqlInstallCredential + ) + + Import-DscResource -ModuleName 'SqlServerDsc' + + node localhost { + SqlServerNetwork 'Integration_Test' + { + ServerName = $Node.ServerName + InstanceName = $Node.InstanceName + ProtocolName = $Node.ProtocolName + IsEnabled = $Node.IsEnabled + TcpDynamicPort = $Node.TcpDynamicPort + + PsDscRunAsCredential = $SqlInstallCredential + } + } +} diff --git a/Tests/Unit/MSFT_SqlServerNetwork.Tests.ps1 b/Tests/Unit/MSFT_SqlServerNetwork.Tests.ps1 index 21efdc997..b203574ae 100644 --- a/Tests/Unit/MSFT_SqlServerNetwork.Tests.ps1 +++ b/Tests/Unit/MSFT_SqlServerNetwork.Tests.ps1 @@ -90,10 +90,6 @@ try $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer' } - $mockFunction_RegisterSqlWmiManagement = { - return [System.AppDomain]::CreateDomain('DummyTestApplicationDomain') - } - $mockDefaultParameters = @{ InstanceName = $mockInstanceName ProtocolName = $mockTcpProtocolName @@ -103,10 +99,7 @@ try BeforeEach { $testParameters = $mockDefaultParameters.Clone() - Mock -CommandName Register-SqlWmiManagement ` - -MockWith $mockFunction_RegisterSqlWmiManagement ` - -Verifiable - + Mock -CommandName Connect-Sql Mock -CommandName New-Object ` -MockWith $mockFunction_NewObject_ManagedComputer ` -ParameterFilter $mockFunction_NewObject_ManagedComputer_ParameterFilter -Verifiable @@ -126,7 +119,6 @@ try $result.TcpDynamicPort | Should -Be $false $result.TcpPort | Should -Be $mockDynamicValue_TcpPort - Assert-MockCalled -CommandName Register-SqlWmiManagement -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName New-Object -Exactly -Times 1 -Scope It ` -ParameterFilter $mockFunction_NewObject_ManagedComputer_ParameterFilter } @@ -145,10 +137,7 @@ try BeforeEach { $testParameters = $mockDefaultParameters.Clone() - Mock -CommandName Register-SqlWmiManagement ` - -MockWith $mockFunction_RegisterSqlWmiManagement ` - -Verifiable - + Mock -CommandName Connect-Sql Mock -CommandName New-Object ` -MockWith $mockFunction_NewObject_ManagedComputer ` -ParameterFilter $mockFunction_NewObject_ManagedComputer_ParameterFilter -Verifiable @@ -314,10 +303,7 @@ try $testParameters = $mockDefaultParameters.Clone() Mock -CommandName Restart-SqlService -Verifiable - Mock -CommandName Register-SqlWmiManagement ` - -MockWith $mockFunction_RegisterSqlWmiManagement ` - -Verifiable - + Mock -CommandName Connect-Sql Mock -CommandName New-Object ` -MockWith $mockFunction_NewObject_ManagedComputer ` -ParameterFilter $mockFunction_NewObject_ManagedComputer_ParameterFilter -Verifiable diff --git a/Tests/Unit/SqlServerDSCHelper.Tests.ps1 b/Tests/Unit/SqlServerDSCHelper.Tests.ps1 index 2b12a6ec9..88788fd39 100644 --- a/Tests/Unit/SqlServerDSCHelper.Tests.ps1 +++ b/Tests/Unit/SqlServerDSCHelper.Tests.ps1 @@ -852,109 +852,6 @@ InModuleScope $script:moduleName { Assert-VerifiableMock } - $mockApplicationDomainName = 'SqlServerDscHelperTests' - $mockApplicationDomainObject = [System.AppDomain]::CreateDomain($mockApplicationDomainName) - - <# - It is not possible to fully test this helper function since we can't mock having the correct assembly - in the GAC. So these test will try to load the wrong assembly and will catch the error. But that means - it will never test the rows after if fails to load the assembly. - #> - Describe 'Testing Register-SqlSmo' -Tag RegisterSqlSmo { - BeforeEach { - Mock -CommandName Get-SqlInstanceMajorVersion -MockWith { - return '0' # Mocking zero because that could never match a correct assembly - } -Verifiable - } - - Context 'When calling Register-SqlSmo to load the wrong assembly' { - It 'Should throw with the correct error' { - { - Register-SqlSmo -SQLInstanceName $mockInstanceName - } | Should -Throw 'Exception calling "Load" with "1" argument(s): "Could not load file or assembly ''Microsoft.SqlServer.Smo, Version=0.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91'' or one of its dependencies. The system cannot find the file specified."' - - Assert-MockCalled -CommandName Get-SqlInstanceMajorVersion - } - } - - Context 'When calling Register-SqlSmo with a application domain to load the wrong assembly' { - It 'Should throw with the correct error' { - { - Register-SqlSmo -SQLInstanceName $mockInstanceName -ApplicationDomain $mockApplicationDomainObject - } | Should -Throw 'Exception calling "Load" with "1" argument(s): "Could not load file or assembly ''Microsoft.SqlServer.Smo, Version=0.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91'' or one of its dependencies. The system cannot find the file specified."' - - Assert-MockCalled -CommandName Get-SqlInstanceMajorVersion - } - } - - Assert-VerifiableMock - } - - <# - It is not possible to fully test this helper function since we can't mock having the correct assembly - in the GAC. So these test will try to load the wrong assembly and will catch the error. But that means - it will never test the rows after if fails to load the assembly. - #> - Describe 'Testing Register-SqlWmiManagement' -Tag RegisterSqlWmiManagement { - BeforeEach { - Mock -CommandName Get-SqlInstanceMajorVersion -MockWith { - return '0' # Mocking zero because that could never match a correct assembly - } -Verifiable - - Mock -CommandName Register-SqlSmo -MockWith { - [System.AppDomain]::CreateDomain('SqlServerDscHelper') - } -ParameterFilter { - $SQLInstanceName -eq $mockInstanceName - } -Verifiable - } - - Context 'When calling Register-SqlWmiManagement to load the wrong assembly' { - It 'Should throw with the correct error' { - { - Register-SqlWmiManagement -SQLInstanceName $mockInstanceName - } | Should -Throw 'Exception calling "Load" with "1" argument(s): "Could not load file or assembly ''Microsoft.SqlServer.SqlWmiManagement, Version=0.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91'' or one of its dependencies. The system cannot find the file specified."' - - Assert-MockCalled -CommandName Get-SqlInstanceMajorVersion - Assert-MockCalled -CommandName Register-SqlSmo -Exactly -Times 1 -Scope It -ParameterFilter { - $SQLInstanceName -eq $mockInstanceName -and $ApplicationDomain -eq $null - } - } - } - - Context 'When calling Register-SqlWmiManagement with a application domain to load the wrong assembly' { - It 'Should throw with the correct error' { - { - Register-SqlWmiManagement -SQLInstanceName $mockInstanceName -ApplicationDomain $mockApplicationDomainObject - } | Should -Throw 'Exception calling "Load" with "1" argument(s): "Could not load file or assembly ''Microsoft.SqlServer.SqlWmiManagement, Version=0.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91'' or one of its dependencies. The system cannot find the file specified."' - - Assert-MockCalled -CommandName Get-SqlInstanceMajorVersion - Assert-MockCalled -CommandName Register-SqlSmo -Exactly -Times 0 -Scope It -ParameterFilter { - $SQLInstanceName -eq $mockInstanceName -and $ApplicationDomain -eq $null - } - - Assert-MockCalled -CommandName Register-SqlSmo -Exactly -Times 1 -Scope It -ParameterFilter { - $SQLInstanceName -eq $mockInstanceName -and $ApplicationDomain.FriendlyName -eq $mockApplicationDomainName - } - } - } - - Assert-VerifiableMock - } - - <# - NOTE! This test must be after the tests for Register-SqlSmo and Register-SqlWmiManagement. - This test unloads the application domain that is used during those tests. - #> - Describe 'Testing Unregister-SqlAssemblies' -Tag UnregisterSqlAssemblies { - Context 'When calling Unregister-SqlAssemblies to unload the assemblies' { - It 'Should not throw an error' { - { - Unregister-SqlAssemblies -ApplicationDomain $mockApplicationDomainObject - } | Should -Not -Throw - } - } - } - Describe 'Testing Get-PrimaryReplicaServerObject' { BeforeEach { $mockServerObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server diff --git a/en-US/SqlServerDscHelper.strings.psd1 b/en-US/SqlServerDscHelper.strings.psd1 index ca2d4614e..33fcb096e 100644 --- a/en-US/SqlServerDscHelper.strings.psd1 +++ b/en-US/SqlServerDscHelper.strings.psd1 @@ -6,10 +6,6 @@ ConvertFrom-StringData @' ConnectedToAnalysisServicesInstance = Connected to Analysis Services instance '{0}'. FailedToConnectToAnalysisServicesInstance = Failed to connected to Analysis Services instance '{0}'. SqlMajorVersion = SQL major version is {0}. - CreatingApplicationDomain = Creating application domain '{0}'. - ReusingApplicationDomain = Reusing application domain '{0}'. - LoadingAssembly = Loading assembly '{0}'. - UnloadingApplicationDomain = Unloading application domain '{0}'. SqlServerVersionIsInvalid = Could not get the SQL version for the instance '{0}'. PropertyTypeInvalidForDesiredValues = Property 'DesiredValues' must be either a [System.Collections.Hashtable], [CimInstance] or [PSBoundParametersDictionary]. The type detected was {0}. PropertyTypeInvalidForValuesToCheck = If 'DesiredValues' is a CimInstance, then property 'ValuesToCheck' must contain a value. diff --git a/sv-SE/SqlServerDscHelper.strings.psd1 b/sv-SE/SqlServerDscHelper.strings.psd1 index 987b25b50..fcf20b6b9 100644 --- a/sv-SE/SqlServerDscHelper.strings.psd1 +++ b/sv-SE/SqlServerDscHelper.strings.psd1 @@ -6,10 +6,6 @@ ConvertFrom-StringData @' ConnectedToAnalysisServicesInstance = Ansluten till Analysis Services instans '{0}'. FailedToConnectToAnalysisServicesInstance = Misslyckades att ansluta till Analysis Services instans '{0}'. SqlMajorVersion = SQL major version är {0}. - CreatingApplicationDomain = Skapar applikationsdomän '{0}'. - ReusingApplicationDomain = Återanvänder applikationsdomän '{0}'. - LoadingAssembly = Laddar samling '{0}'. - UnloadingApplicationDomain = Återställer applikationsdomän '{0}'. SqlServerVersionIsInvalid = Kunde inte hämta SQL version för instansen '{0}'. PropertyTypeInvalidForDesiredValues = Egenskapen 'DesiredValues' måste vara endera en [System.Collections.Hashtable], [CimInstance] eller [PSBoundParametersDictionary]. Den typ som hittades var {0}. PropertyTypeInvalidForValuesToCheck = Om 'DesiredValues' är av typ CimInstance, då måste egenskapen 'ValuesToCheck' sättas till ett värde. @@ -37,7 +33,7 @@ ConvertFrom-StringData @' ExecuteQueryWithResultsFailed = Exekvering av fråga med resultat misslyckades mot databas '{0}'. ExecuteNonQueryFailed = Exekvering av icke-fråga misslyckades på databas '{0}'. AlterAvailabilityGroupReplicaFailed = Misslyckades att ändra Availability Group kopia '{0}'. - GetEffectivePermissionForLogin = Hämtar effektiva behörigeter för inloggningen '{0}' på '{1}'. + GetEffectivePermissionForLogin = Hämtar effektiva behörigheter för inloggningen '{0}' på '{1}'. # - NOTE! # - Below strings are used by helper functions New-TerminatingError and New-WarningMessage.