From 8df83b35aea313a9ae846fed1b72d2c8369fb7a0 Mon Sep 17 00:00:00 2001 From: Maxime DANIOU Date: Mon, 21 Jan 2019 15:53:42 +0100 Subject: [PATCH 1/4] SqlServerEndpoint : Add parameter "Owner" --- CHANGELOG.md | 5 ++ .../MSFT_SqlServerEndpoint.psm1 | 42 +++++++++- .../MSFT_SqlServerEndpoint.schema.mof | 1 + ...ndpointWithSpecificPortIPAddressOwner.ps1} | 3 +- README.md | 4 +- Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 | 80 +++++++++++++++++-- 6 files changed, 123 insertions(+), 12 deletions(-) rename Examples/Resources/SqlServerEndpoint/{2-CreateEndpointWithSpecificPortAndIPAddress.ps1 => 2-CreateEndpointWithSpecificPortIPAddressOwner.ps1} (81%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64844af0e..fa277c66f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,11 @@ - Updated the integration test to stop the named instance while installing the other instances to mitigate [issue #1260](https://github.com/PowerShell/SqlServerDsc/issues/1260). +- Changes to SqlServerEndpoint + - Add the optional parameter Owner. The default owner remains the login used for + the creation of the endpoint + ([issue #1251](https://github.com/PowerShell/SqlServerDsc/issues/1251). + [Maxime Daniou (@mdaniou)](https://github.com/mdaniou) ## 12.2.0.0 diff --git a/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 b/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 index 1bc760540..2355333b8 100644 --- a/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 +++ b/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 @@ -40,6 +40,7 @@ function Get-TargetResource EndpointName = '' Port = '' IpAddress = '' + Owner = '' } $sqlServerObject = Connect-SQL -ServerName $ServerName -InstanceName $InstanceName @@ -61,6 +62,7 @@ function Get-TargetResource $getTargetResourceReturnValues.EndpointName = $endpointObject.Name $getTargetResourceReturnValues.Port = $endpointObject.Protocol.Tcp.ListenerPort $getTargetResourceReturnValues.IpAddress = $endpointObject.Protocol.Tcp.ListenerIPAddress + $getTargetResourceReturnValues.Owner = $endpointObject.Owner } else { @@ -68,6 +70,7 @@ function Get-TargetResource $getTargetResourceReturnValues.EndpointName = '' $getTargetResourceReturnValues.Port = '' $getTargetResourceReturnValues.IpAddress = '' + $getTargetResourceReturnValues.Owner = '' } } else @@ -101,6 +104,9 @@ function Get-TargetResource .PARAMETER IpAddress The network IP address the endpoint is listening on. Defaults to '0.0.0.0' which means listen on any valid IP address. + + .PARAMETER Owner + The owner of the endpoint. Default is the login used for the creation. #> function Set-TargetResource { @@ -130,7 +136,11 @@ function Set-TargetResource [Parameter()] [System.String] - $IpAddress = '0.0.0.0' + $IpAddress = '0.0.0.0', + + [Parameter()] + [System.String] + $Owner ) $getTargetResourceResult = Get-TargetResource -EndpointName $EndpointName -ServerName $ServerName -InstanceName $InstanceName @@ -147,6 +157,12 @@ function Set-TargetResource $endpointObject.ProtocolType = [Microsoft.SqlServer.Management.Smo.ProtocolType]::Tcp $endpointObject.Protocol.Tcp.ListenerPort = $Port $endpointObject.Protocol.Tcp.ListenerIPAddress = $IpAddress + + if ($PSBoundParameters.ContainsKey('Owner')) + { + $endpointObject.Owner = $Owner + } + $endpointObject.Payload.DatabaseMirroring.ServerMirroringRole = [Microsoft.SqlServer.Management.Smo.ServerMirroringRole]::All $endpointObject.Payload.DatabaseMirroring.EndpointEncryption = [Microsoft.SqlServer.Management.Smo.EndpointEncryption]::Required $endpointObject.Payload.DatabaseMirroring.EndpointEncryptionAlgorithm = [Microsoft.SqlServer.Management.Smo.EndpointEncryptionAlgorithm]::Aes @@ -172,6 +188,13 @@ function Set-TargetResource $endpointObject.Protocol.Tcp.ListenerPort = $Port $endpointObject.Alter() } + + if ($endpointObject.Owner -ne $Owner) + { + Write-Verbose -Message ('Updating endpoint {0} Owner to {1}.' -f $EndpointName, $Owner) + $endpointObject.Owner = $Owner + $endpointObject.Alter() + } } else { @@ -222,6 +245,9 @@ function Set-TargetResource .PARAMETER IpAddress The network IP address the endpoint is listening on. Defaults to '0.0.0.0' which means listen on any valid IP address. + + .PARAMETER Owner + The owner of the endpoint. Default is the login used for the creation. #> function Test-TargetResource { @@ -252,7 +278,11 @@ function Test-TargetResource [Parameter()] [System.String] - $IpAddress = '0.0.0.0' + $IpAddress = '0.0.0.0', + + [Parameter()] + [System.String] + $Owner ) $getTargetResourceResult = Get-TargetResource -EndpointName $EndpointName -ServerName $ServerName -InstanceName $InstanceName @@ -262,10 +292,14 @@ function Test-TargetResource if ($getTargetResourceResult.Ensure -eq 'Present' ` -and ( - $getTargetResourceResult.Port -ne $Port ` + $getTargetResourceResult.Port -ne $Port ` -or $getTargetResourceResult.IpAddress -ne $IpAddress - ) + ) ) + { + $result = $false + } + elseif ($getTargetResourceResult.Ensure -eq 'Present' -and $Owner) { $result = $false } diff --git a/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof b/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof index 05c85cfab..214feca2b 100644 --- a/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof +++ b/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof @@ -7,4 +7,5 @@ class MSFT_SqlServerEndpoint : OMI_BaseResource [Write, Description("The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME.")] String ServerName; [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; [Write, Description("The network IP address the endpoint is listening on. Default the endpoint will listen on any valid IP address.")] String IpAddress; + [Write, Description("The owner of the endpoint. Default is the login used for the creation.")] String EndPointOwner; }; diff --git a/Examples/Resources/SqlServerEndpoint/2-CreateEndpointWithSpecificPortAndIPAddress.ps1 b/Examples/Resources/SqlServerEndpoint/2-CreateEndpointWithSpecificPortIPAddressOwner.ps1 similarity index 81% rename from Examples/Resources/SqlServerEndpoint/2-CreateEndpointWithSpecificPortAndIPAddress.ps1 rename to Examples/Resources/SqlServerEndpoint/2-CreateEndpointWithSpecificPortIPAddressOwner.ps1 index 973332ab9..e3e4c4d8c 100644 --- a/Examples/Resources/SqlServerEndpoint/2-CreateEndpointWithSpecificPortAndIPAddress.ps1 +++ b/Examples/Resources/SqlServerEndpoint/2-CreateEndpointWithSpecificPortIPAddressOwner.ps1 @@ -1,6 +1,6 @@ <# .EXAMPLE - This example will add a Database Mirror endpoint with a specific listener port and a specific listener IP address. + This example will add a Database Mirror endpoint with specific listener port, listener IP address and owner. #> Configuration Example { @@ -22,6 +22,7 @@ Configuration Example EndpointName = 'HADR' Port = 9001 IpAddress = '192.168.0.20' + Owner = 'sa' ServerName = 'server1.company.local' InstanceName = 'INST1' diff --git a/README.md b/README.md index 4c417e0ff..f124cd027 100644 --- a/README.md +++ b/README.md @@ -1041,11 +1041,13 @@ the resource [**SqlServerEndpointPermission**](#sqlserverendpointpermission). * **`[String]` InstanceName** _(Key)_: The name of the SQL instance to be configured. * **`[String]` IpAddress** _(Write)_: The network IP address the endpoint is listening on. Defaults to '0.0.0.0' which means listen on any valid IP address. +* **`[String]` Owner** _(Write)_: The owner of the endpoint. Default is the login used + for the creation. #### Examples * [Create an endpoint with default values](/Examples/Resources/SqlServerEndpoint/1-CreateEndpointWithDefaultValues.ps1) -* [Create an endpoint with specific port and IP address](/Examples/Resources/SqlServerEndpoint/2-CreateEndpointWithSpecificPortAndIPAddress.ps1) +* [Create an endpoint with specific port and IP address](/Examples/Resources/SqlServerEndpoint/2-CreateEndpointWithSpecificPortIPAddressOwner.ps1) * [Remove an endpoint](/Examples/Resources/SqlServerEndpoint/3-RemoveEndpoint.ps1) #### Known issues diff --git a/Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 b/Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 index 1800e7be8..3eb76f297 100644 --- a/Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 +++ b/Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 @@ -59,11 +59,13 @@ try $mockEndpointType = 'DatabaseMirroring' $mockEndpointListenerPort = 5022 $mockEndpointListenerIpAddress = '0.0.0.0' # 0.0.0.0 means listen on all IP addresses. + $mockEndpointOwner = 'sa' $mockOtherEndpointName = 'UnknownEndpoint' $mockOtherEndpointType = 'UnknownType' $mockOtherEndpointListenerPort = 9001 $mockOtherEndpointListenerIpAddress = '192.168.0.20' + $mockOtherEndpointOwner = 'COMPANY\OtherAcct' $script:mockMethodAlterRan = $false $script:mockMethodCreateRan = $false @@ -74,6 +76,7 @@ try $mockDynamicEndpointType = $mockEndpointType $mockDynamicEndpointListenerPort = $mockEndpointListenerPort $mockDynamicEndpointListenerIpAddress = $mockEndpointListenerIpAddress + $mockDynamicEndpointOwner = $mockEndpointOwner $mockEndpointObject = { # TypeName: Microsoft.SqlServer.Management.Smo.Endpoint @@ -81,6 +84,7 @@ try Add-Member -MemberType NoteProperty -Name 'Name' -Value $mockDynamicEndpointName -PassThru | Add-Member -MemberType NoteProperty -Name 'EndpointType' -Value $mockDynamicEndpointType -PassThru | Add-Member -MemberType NoteProperty -Name 'ProtocolType' -Value $null -PassThru | + Add-Member -MemberType NoteProperty -Name 'Owner' -Value $mockDynamicEndpointOwner -PassThru | Add-Member -MemberType ScriptProperty -Name 'Protocol' -Value { return New-Object -TypeName Object | Add-Member -MemberType ScriptProperty -Name 'Tcp' -Value { @@ -184,6 +188,7 @@ try $result.EndpointName | Should -Be '' $result.Port | Should -Be '' $result.IpAddress | Should -Be '' + $result.Owner | Should -Be '' } It 'Should call the mock function Connect-SQL' { @@ -208,6 +213,7 @@ try $result.EndpointName | Should -Be $testParameters.EndpointName $result.Port | Should -Be $mockEndpointListenerPort $result.IpAddress | Should -Be $mockEndpointListenerIpAddress + $result.Owner | Should -Be $mockEndpointOwner } It 'Should call the mock function Connect-SQL' { @@ -265,6 +271,7 @@ try $testParameters.Add('Ensure', 'Present') $testParameters.Add('Port', $mockEndpointListenerPort) $testParameters.Add('IpAddress', $mockEndpointListenerIpAddress) + $testParameters.Add('Owner', $mockEndpointOwner) $result = Test-TargetResource @testParameters $result | Should -Be $false @@ -322,6 +329,26 @@ try # Make sure the mock do return the correct endpoint listener IP address $mockDynamicEndpointListenerIpAddress = $mockEndpointListenerIpAddress + + # Make sure the mock do return the correct endpoint, but does not return the correct endpoint listener IP address + $mockDynamicEndpointName = $mockEndpointName + $mockDynamicEndpointOwner = $mockOtherEndpointOwner + + Context 'When listener Owner is not in desired state' { + It 'Should return that desired state is absent' { + $testParameters.Add('Ensure', 'Present') + $testParameters.Add('Owner', $mockEndpointOwner) + + + $result = Test-TargetResource @testParameters + $result | Should -Be $false + + Assert-MockCalled Connect-SQL -Exactly -Times 1 -Scope It + } + } + + # Make sure the mock do return the correct endpoint listener IP address + $mockDynamicEndpointOwner = $mockEndpointOwner } Context 'When the system is in the desired state' { @@ -372,7 +399,7 @@ try # Set what the expected endpoint name should be when Create() method is called. $mockExpectedNameWhenCallingMethod = $mockEndpointName - It 'Should call the the method Create when desired state is to be Present (using default values)' { + It 'Should call the method Create when desired state is to be Present (using default values)' { Mock -CommandName Get-TargetResource -MockWith { return @{ Ensure = 'Absent' @@ -397,7 +424,7 @@ try # Set what the expected endpoint name should be when Create() method is called. $mockExpectedNameWhenCallingMethod = $mockEndpointName - It 'Should call the the method Create when desired state is to be Present (setting all parameters)' { + It 'Should call the method Create when desired state is to be Present (setting all parameters)' { Mock -CommandName Get-TargetResource -MockWith { return @{ Ensure = 'Absent' @@ -407,6 +434,7 @@ try $testParameters.Add('Ensure', 'Present') $testParameters.Add('Port', $mockEndpointListenerPort) $testParameters.Add('IpAddress', $mockEndpointListenerIpAddress) + $testParameters.Add('Owner', $mockEndpointOwner) { Set-TargetResource @testParameters } | Should -Not -Throw $script:mockMethodCreateRan | Should -Be $true @@ -426,7 +454,7 @@ try # Set what the expected endpoint name should be when Drop() method is called. $mockExpectedNameWhenCallingMethod = $mockEndpointName - It 'Should call the the method Drop when desired state is to be Absent' { + It 'Should call the method Drop when desired state is to be Absent' { Mock -CommandName Get-TargetResource -MockWith { return @{ Ensure = 'Present' @@ -453,7 +481,7 @@ try # Set what the expected endpoint name should be when Alter() method is called. $mockExpectedNameWhenCallingMethod = $mockEndpointName - It 'Should not call Alter method when listener port is not in desired state' { + It 'Should call Alter method when listener port is not in desired state' { Mock -CommandName Get-TargetResource -MockWith { return @{ Ensure = 'Present' @@ -465,6 +493,7 @@ try $testParameters.Add('Ensure', 'Present') $testParameters.Add('Port', $mockOtherEndpointListenerPort) $testParameters.Add('IpAddress', $mockEndpointListenerIpAddress) + $testParameters.Add('Owner', $mockEndpointOwner) { Set-TargetResource @testParameters } | Should -Not -Throw $script:mockMethodCreateRan | Should -Be $false @@ -484,7 +513,7 @@ try # Set what the expected endpoint name should be when Alter() method is called. $mockExpectedNameWhenCallingMethod = $mockEndpointName - It 'Should not call Alter method when listener IP address is not in desired state' { + It 'Should call Alter method when listener IP address is not in desired state' { Mock -CommandName Get-TargetResource -MockWith { return @{ Ensure = 'Present' @@ -496,6 +525,39 @@ try $testParameters.Add('Ensure', 'Present') $testParameters.Add('Port', $mockEndpointListenerPort) $testParameters.Add('IpAddress', $mockOtherEndpointListenerIpAddress) + $testParameters.Add('Owner', $mockEndpointOwner) + + { Set-TargetResource @testParameters } | Should -Not -Throw + $script:mockMethodCreateRan | Should -Be $false + $script:mockMethodStartRan | Should -Be $false + $script:mockMethodAlterRan | Should -Be $true + $script:mockMethodDropRan | Should -Be $false + + Assert-MockCalled Connect-SQL -Exactly -Times 1 -Scope It + } + + # Set all method call tests variables to $false + $script:mockMethodCreateRan = $false + $script:mockMethodStartRan = $false + $script:mockMethodAlterRan = $false + $script:mockMethodDropRan = $false + + # Set what the expected endpoint name should be when Alter() method is called. + $mockExpectedNameWhenCallingMethod = $mockEndpointName + + It 'Should call Alter method when Owner is not in desired state' { + Mock -CommandName Get-TargetResource -MockWith { + return @{ + Ensure = 'Present' + Port = $mockEndpointListenerPort + IpAddress = $mockEndpointListenerIpAddress + } + } -Verifiable + + $testParameters.Add('Ensure', 'Present') + $testParameters.Add('Port', $mockEndpointListenerPort) + $testParameters.Add('IpAddress', $mockEndpointListenerIpAddress) + $testParameters.Add('Owner', $mockOtherEndpointOwner) { Set-TargetResource @testParameters } | Should -Not -Throw $script:mockMethodCreateRan | Should -Be $false @@ -516,6 +578,7 @@ try Ensure = 'Present' Port = $mockEndpointListenerPort IpAddress = $mockEndpointListenerIpAddress + Owner = $mockEndpointOwner } } -Verifiable @@ -530,6 +593,7 @@ try Ensure = 'Present' Port = $mockEndpointListenerPort IpAddress = $mockEndpointListenerIpAddress + Owner = $mockEndpointOwner } } -Verifiable @@ -551,11 +615,12 @@ try } } - Context 'When the system is in the desired state' { + Context ' ' { # Make sure the mock do return the correct endpoint $mockDynamicEndpointName = $mockEndpointName $mockDynamicEndpointListenerPort = $mockEndpointListenerPort $mockDynamicEndpointListenerIpAddress = $mockEndpointListenerIpAddress + $mockDynamicEndpointOwner = $mockEndpointOwner # Set all method call tests variables to $false $script:mockMethodCreateRan = $false @@ -569,12 +634,14 @@ try Ensure = 'Present' Port = $mockEndpointListenerPort IpAddress = $mockEndpointListenerIpAddress + Owner = $mockEndpointOwner } } -Verifiable $testParameters.Add('Ensure', 'Present') $testParameters.Add('Port', $mockEndpointListenerPort) $testParameters.Add('IpAddress', $mockEndpointListenerIpAddress) + $testParameters.Add('Owner', $mockEndpointOwner) { Set-TargetResource @testParameters } | Should -Not -Throw $script:mockMethodCreateRan | Should -Be $false @@ -657,6 +724,7 @@ try $testParameters.Add('Ensure', 'Present') $testParameters.Add('Port', $mockOtherEndpointListenerPort) $testParameters.Add('IpAddress', $mockEndpointListenerIpAddress) + $testParameters.Add('Owner', $mockEndpointOwner) { Set-TargetResource @testParameters } | Should -Throw 'Exception calling "Alter" with "0" argument(s): "Called mocked Alter() method on and endpoint with wrong name. Expected ''UnknownEndpoint''. But was ''DefaultEndpointMirror''."' } From 465d2f84bae0fcbf1ded6ce73d7339b81375b93c Mon Sep 17 00:00:00 2001 From: Maxime DANIOU Date: Tue, 22 Jan 2019 09:53:27 +0100 Subject: [PATCH 2/4] Fix errors related to tabs, trailing spaces, line length and wrong parameter name in the Schema file --- CHANGELOG.md | 4 +- .../MSFT_SqlServerEndpoint.psm1 | 2 +- .../MSFT_SqlServerEndpoint.schema.mof | 2 +- README.md | 4 +- ...FT_SqlServerEndPoint.Integration.Tests.ps1 | 139 ++++++++++++++++++ .../MSFT_SqlServerEndPoint.config.ps1 | 70 +++++++++ Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 | 2 +- 7 files changed, 216 insertions(+), 7 deletions(-) create mode 100644 Tests/Integration/MSFT_SqlServerEndPoint.Integration.Tests.ps1 create mode 100644 Tests/Integration/MSFT_SqlServerEndPoint.config.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index fa277c66f..b860c97aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,8 +39,8 @@ the other instances to mitigate [issue #1260](https://github.com/PowerShell/SqlServerDsc/issues/1260). - Changes to SqlServerEndpoint - - Add the optional parameter Owner. The default owner remains the login used for - the creation of the endpoint + - Add the optional parameter Owner. The default owner remains the login used + for the creation of the endpoint ([issue #1251](https://github.com/PowerShell/SqlServerDsc/issues/1251). [Maxime Daniou (@mdaniou)](https://github.com/mdaniou) diff --git a/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 b/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 index 2355333b8..7638713b2 100644 --- a/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 +++ b/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 @@ -299,7 +299,7 @@ function Test-TargetResource { $result = $false } - elseif ($getTargetResourceResult.Ensure -eq 'Present' -and $Owner) + elseif ($getTargetResourceResult.Ensure -eq 'Present' -and $Owner) { $result = $false } diff --git a/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof b/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof index 214feca2b..9b421ae63 100644 --- a/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof +++ b/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof @@ -7,5 +7,5 @@ class MSFT_SqlServerEndpoint : OMI_BaseResource [Write, Description("The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME.")] String ServerName; [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; [Write, Description("The network IP address the endpoint is listening on. Default the endpoint will listen on any valid IP address.")] String IpAddress; - [Write, Description("The owner of the endpoint. Default is the login used for the creation.")] String EndPointOwner; + [Write, Description("The owner of the endpoint. Default is the login used for the creation.")] String Owner; }; diff --git a/README.md b/README.md index f124cd027..9501f2fb2 100644 --- a/README.md +++ b/README.md @@ -1041,8 +1041,8 @@ the resource [**SqlServerEndpointPermission**](#sqlserverendpointpermission). * **`[String]` InstanceName** _(Key)_: The name of the SQL instance to be configured. * **`[String]` IpAddress** _(Write)_: The network IP address the endpoint is listening on. Defaults to '0.0.0.0' which means listen on any valid IP address. -* **`[String]` Owner** _(Write)_: The owner of the endpoint. Default is the login used - for the creation. +* **`[String]` Owner** _(Write)_: The owner of the endpoint. Default is the + login used for the creation. #### Examples diff --git a/Tests/Integration/MSFT_SqlServerEndPoint.Integration.Tests.ps1 b/Tests/Integration/MSFT_SqlServerEndPoint.Integration.Tests.ps1 new file mode 100644 index 000000000..3ae761cb7 --- /dev/null +++ b/Tests/Integration/MSFT_SqlServerEndPoint.Integration.Tests.ps1 @@ -0,0 +1,139 @@ +<# + .SYNOPSIS + Template for creating DSC Resource Integration Tests + + .DESCRIPTION + To Use: + 1. Copy to \Tests\Integration\ folder and rename .Integration.tests.ps1 + (e.g. MSFT_Firewall.Integration.tests.ps1). + 2. Customize TODO sections. + 3. Remove TODO comments. + 4. Create test DSC Configuration file .config.ps1 + (e.g. MSFT_Firewall.config.ps1) from integration_template.config.ps1 file. + 5. Remove this comment-based help. + + .NOTES + Code in HEADER and FOOTER regions are standard and should not be altered + if possible. +#> + +# TODO: Customize these parameters... +$script:dscModuleName = 'SqlServerDsc' +$script:dscResourceFriendlyName = 'SqlServerEndpoint' +$script:dcsResourceName = "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 +} + +if ($env:APPVEYOR -eq $true -and $env:CONFIGURATION -ne 'Integration') +{ + Write-Verbose -Message ('Integration test for {0} will be skipped unless $env:CONFIGURATION is set to ''Integration''.' -f $script:DSCResourceName) -Verbose + return +} + +#region HEADER +# Integration Test Template Version: 1.3.1 +[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:dcsResourceName ` + -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 + +# Using try/finally to always cleanup. +try +{ + #region Integration Tests + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dcsResourceName).config.ps1" + . $configurationFile + + Describe "$($script:dcsResourceName)_Integration" { + # TODO: Update with the correct name of the configuration. + $configurationName = "$($script:dcsResourceName)_Create_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + <# + TODO: (Optional) Add any additional parameters needed + for compilation of the configuration, like credentials. + #> + $configurationParameters = @{ + OutputPath = $TestDrive + <# + TODO: The variable $ConfigurationData was dot-sourced + above. (Optional) The configuration data hash table can + be moved into this file as appropriate, see the + integration_template.config.ps1 for more information. + #> + 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 ` + -and $_.ResourceId -eq "[$($script:dscResourceFriendlyName)]Integration_Test" + } + + # TODO: Validate the Config was Set Correctly Here... + $resourceCurrentState.Ensure | Should -Be 'Present' + $resourceCurrentState.Property | Should -Be $ConfigurationData.AllNodes.Property1 + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be $true + } + } + + <# + TODO: (Optional) Add a new context block for the next configuration + that should be tested. + #> + + } + #endregion + +} +finally +{ + #region FOOTER + Restore-TestEnvironment -TestEnvironment $TestEnvironment + #endregion + + # TODO: (Optional) Other cleanup code goes here. +} diff --git a/Tests/Integration/MSFT_SqlServerEndPoint.config.ps1 b/Tests/Integration/MSFT_SqlServerEndPoint.config.ps1 new file mode 100644 index 000000000..eaae17b8b --- /dev/null +++ b/Tests/Integration/MSFT_SqlServerEndPoint.config.ps1 @@ -0,0 +1,70 @@ +#region HEADER +# Integration Test Config Template Version: 1.2.0 +#endregion + + +$ConfigurationData = @{ + AllNodes = @( + @{ + NodeName = 'localhost' + ServerName = $env:COMPUTERNAME + InstanceName = 'DSCSQL2016' + + EndpointName = 'HADR' + Port = 5023 + IpAddress = '10.10.10.10' + Owner = 'sa' + + CertificateFile = $env:DscPublicCertificatePath + } + ) +} + +<# + .SYNOPSIS + Configuration to ensure present and specify all the parameters +#> +Configuration MSFT_SqlServerEndpoint_Create_Config +{ + Import-DscResource -ModuleName 'SqlServerDsc' + + node localhost + { + SqlServerEndpoint Integration_Test + { + Ensure = 'Present' + + EndpointName = $Node.EndpointName + Port = $Node.Port + IpAddress = $Node.IpAddress + #Owner = $Node.Owner ## NOT UNCOMMENT WHEN ISSUE 1251 FIXED + + ServerName = $Node.ServerName + InstanceName = $Node.InstanceName + } + } +} + +<# + .SYNOPSIS + Configuration to ensure Absent and specify all the parameters +#> +Configuration MSFT_SqlServerEndpoint_Drop_Config +{ + Import-DscResource -ModuleName 'SqlServerDsc' + + node localhost + { + SqlServerEndpoint Integration_Test + { + Ensure = 'Absent' + + EndpointName = $Node.EndpointName + + ServerName = $Node.ServerName + InstanceName = $Node.InstanceName + } + } +} + + diff --git a/Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 b/Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 index 3eb76f297..3171d2432 100644 --- a/Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 +++ b/Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 @@ -615,7 +615,7 @@ try } } - Context ' ' { + Context ' ' { # Make sure the mock do return the correct endpoint $mockDynamicEndpointName = $mockEndpointName $mockDynamicEndpointListenerPort = $mockEndpointListenerPort From af55ff531f6451292ae90594c57dd81d315a4522 Mon Sep 17 00:00:00 2001 From: Maxime DANIOU Date: Tue, 22 Jan 2019 10:04:44 +0100 Subject: [PATCH 3/4] Oups, remove files adding to the wrong branch .. :( --- ...FT_SqlServerEndPoint.Integration.Tests.ps1 | 139 ------------------ .../MSFT_SqlServerEndPoint.config.ps1 | 70 --------- 2 files changed, 209 deletions(-) delete mode 100644 Tests/Integration/MSFT_SqlServerEndPoint.Integration.Tests.ps1 delete mode 100644 Tests/Integration/MSFT_SqlServerEndPoint.config.ps1 diff --git a/Tests/Integration/MSFT_SqlServerEndPoint.Integration.Tests.ps1 b/Tests/Integration/MSFT_SqlServerEndPoint.Integration.Tests.ps1 deleted file mode 100644 index 3ae761cb7..000000000 --- a/Tests/Integration/MSFT_SqlServerEndPoint.Integration.Tests.ps1 +++ /dev/null @@ -1,139 +0,0 @@ -<# - .SYNOPSIS - Template for creating DSC Resource Integration Tests - - .DESCRIPTION - To Use: - 1. Copy to \Tests\Integration\ folder and rename .Integration.tests.ps1 - (e.g. MSFT_Firewall.Integration.tests.ps1). - 2. Customize TODO sections. - 3. Remove TODO comments. - 4. Create test DSC Configuration file .config.ps1 - (e.g. MSFT_Firewall.config.ps1) from integration_template.config.ps1 file. - 5. Remove this comment-based help. - - .NOTES - Code in HEADER and FOOTER regions are standard and should not be altered - if possible. -#> - -# TODO: Customize these parameters... -$script:dscModuleName = 'SqlServerDsc' -$script:dscResourceFriendlyName = 'SqlServerEndpoint' -$script:dcsResourceName = "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 -} - -if ($env:APPVEYOR -eq $true -and $env:CONFIGURATION -ne 'Integration') -{ - Write-Verbose -Message ('Integration test for {0} will be skipped unless $env:CONFIGURATION is set to ''Integration''.' -f $script:DSCResourceName) -Verbose - return -} - -#region HEADER -# Integration Test Template Version: 1.3.1 -[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:dcsResourceName ` - -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 - -# Using try/finally to always cleanup. -try -{ - #region Integration Tests - $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dcsResourceName).config.ps1" - . $configurationFile - - Describe "$($script:dcsResourceName)_Integration" { - # TODO: Update with the correct name of the configuration. - $configurationName = "$($script:dcsResourceName)_Create_Config" - - Context ('When using configuration {0}' -f $configurationName) { - It 'Should compile and apply the MOF without throwing' { - { - <# - TODO: (Optional) Add any additional parameters needed - for compilation of the configuration, like credentials. - #> - $configurationParameters = @{ - OutputPath = $TestDrive - <# - TODO: The variable $ConfigurationData was dot-sourced - above. (Optional) The configuration data hash table can - be moved into this file as appropriate, see the - integration_template.config.ps1 for more information. - #> - 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 ` - -and $_.ResourceId -eq "[$($script:dscResourceFriendlyName)]Integration_Test" - } - - # TODO: Validate the Config was Set Correctly Here... - $resourceCurrentState.Ensure | Should -Be 'Present' - $resourceCurrentState.Property | Should -Be $ConfigurationData.AllNodes.Property1 - } - - It 'Should return $true when Test-DscConfiguration is run' { - Test-DscConfiguration -Verbose | Should -Be $true - } - } - - <# - TODO: (Optional) Add a new context block for the next configuration - that should be tested. - #> - - } - #endregion - -} -finally -{ - #region FOOTER - Restore-TestEnvironment -TestEnvironment $TestEnvironment - #endregion - - # TODO: (Optional) Other cleanup code goes here. -} diff --git a/Tests/Integration/MSFT_SqlServerEndPoint.config.ps1 b/Tests/Integration/MSFT_SqlServerEndPoint.config.ps1 deleted file mode 100644 index eaae17b8b..000000000 --- a/Tests/Integration/MSFT_SqlServerEndPoint.config.ps1 +++ /dev/null @@ -1,70 +0,0 @@ -#region HEADER -# Integration Test Config Template Version: 1.2.0 -#endregion - - -$ConfigurationData = @{ - AllNodes = @( - @{ - NodeName = 'localhost' - ServerName = $env:COMPUTERNAME - InstanceName = 'DSCSQL2016' - - EndpointName = 'HADR' - Port = 5023 - IpAddress = '10.10.10.10' - Owner = 'sa' - - CertificateFile = $env:DscPublicCertificatePath - } - ) -} - -<# - .SYNOPSIS - Configuration to ensure present and specify all the parameters -#> -Configuration MSFT_SqlServerEndpoint_Create_Config -{ - Import-DscResource -ModuleName 'SqlServerDsc' - - node localhost - { - SqlServerEndpoint Integration_Test - { - Ensure = 'Present' - - EndpointName = $Node.EndpointName - Port = $Node.Port - IpAddress = $Node.IpAddress - #Owner = $Node.Owner ## NOT UNCOMMENT WHEN ISSUE 1251 FIXED - - ServerName = $Node.ServerName - InstanceName = $Node.InstanceName - } - } -} - -<# - .SYNOPSIS - Configuration to ensure Absent and specify all the parameters -#> -Configuration MSFT_SqlServerEndpoint_Drop_Config -{ - Import-DscResource -ModuleName 'SqlServerDsc' - - node localhost - { - SqlServerEndpoint Integration_Test - { - Ensure = 'Absent' - - EndpointName = $Node.EndpointName - - ServerName = $Node.ServerName - InstanceName = $Node.InstanceName - } - } -} - - From 02b5aad695dad6c11ccbabacf14862ab5f555c9c Mon Sep 17 00:00:00 2001 From: Maxime DANIOU Date: Thu, 24 Jan 2019 07:56:27 +0100 Subject: [PATCH 4/4] Code review changes : Consolidate Test and Modify Unit test text --- .../MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 | 4 +++- Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 b/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 index 7638713b2..c55f2d9f3 100644 --- a/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 +++ b/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 @@ -299,7 +299,9 @@ function Test-TargetResource { $result = $false } - elseif ($getTargetResourceResult.Ensure -eq 'Present' -and $Owner) + elseif ($getTargetResourceResult.Ensure -eq 'Present' -and $Owner ` + -and $getTargetResourceResult.Owner -ne $Owner + ) { $result = $false } diff --git a/Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 b/Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 index 3171d2432..eabf97fa0 100644 --- a/Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 +++ b/Tests/Unit/MSFT_SqlServerEndpoint.Tests.ps1 @@ -330,7 +330,7 @@ try # Make sure the mock do return the correct endpoint listener IP address $mockDynamicEndpointListenerIpAddress = $mockEndpointListenerIpAddress - # Make sure the mock do return the correct endpoint, but does not return the correct endpoint listener IP address + # Make sure the mock do return the correct endpoint, but does not return the correct endpoint owner $mockDynamicEndpointName = $mockEndpointName $mockDynamicEndpointOwner = $mockOtherEndpointOwner @@ -347,7 +347,7 @@ try } } - # Make sure the mock do return the correct endpoint listener IP address + # Make sure the mock do return the correct endpoint owner $mockDynamicEndpointOwner = $mockEndpointOwner }