Skip to content

Commit

Permalink
SqlAlwaysOnService: Update integration tests to use loopback adapter (d…
Browse files Browse the repository at this point in the history
…sccommunity#1110)

- Changes to CommonTestHelpers
  - Added new test helper functions in the CommonTestHelpers module. These are used
    by the integration tests.
- Changes to SqlAlwaysOnService
  - Updated the integration tests to use a loopback adapter to be less intrusive
    in the build worker environment.
  • Loading branch information
johlju authored Apr 16, 2018
1 parent a1d3ea4 commit b2c3602
Show file tree
Hide file tree
Showing 5 changed files with 373 additions and 30 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@

## Unreleased

- Changes to SqlServerDsc
- Added new test helper functions in the CommonTestHelpers module. These are used
by the integration tests.
- **New-IntegrationLoopbackAdapter:** Installs the PowerShell module
'LoopbackAdapter' from PowerShell Gallery and creates a new network
loopback adapter.
- **Remove-IntegrationLoopbackAdapter:** Removes a new network loopback adapter.
- **Get-NetIPAddressNetwork:** Returns the IP network address from an IPv4 address
and prefix length.
- Changes to Unit Tests
- [Michael Fyffe (@TraGicCode)](https://github.com/TraGicCode): Updated
the following resources unit test template to version 1.2.1
- SqlWaitForAG ([issue #1088](https://github.com/PowerShell/SqlServerDsc/issues/1088)).
- Changes to SqlAlwaysOnService
- Updated the integration tests to use a loopback adapter to be less intrusive
in the build worker environment.

## 11.1.0.0

Expand Down
107 changes: 97 additions & 10 deletions Tests/Integration/MSFT_SqlAlwaysOnService.Integration.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ $TestEnvironment = Initialize-TestEnvironment `

#endregion

$integrationErrorMessagePrefix = 'INTEGRATION ERROR MESSAGE:'

$testRootFolderPath = Split-Path -Path $PSScriptRoot -Parent
Import-Module -Name (Join-Path -Path $testRootFolderPath -ChildPath (Join-Path -Path 'TestHelpers' -ChildPath 'CommonTestHelper.psm1')) -Force

$mockSqlInstallAccountPassword = ConvertTo-SecureString -String 'P@ssw0rd1' -AsPlainText -Force
$mockSqlInstallAccountUserName = "$env:COMPUTERNAME\SqlInstall"
$mockSqlInstallCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $mockSqlInstallAccountUserName, $mockSqlInstallAccountPassword
Expand All @@ -34,6 +39,18 @@ try
$configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:DSCResourceName).config.ps1"
. $configFile

# These sets variables used for verification from the dot-sourced $ConfigurationData variable.
$mockLoopbackAdapterName = $ConfigurationData.AllNodes.LoopbackAdapterName

<#
Create the loopback adapter to be used with the cluster.
The loopback adapter is kept on the build worker after test finishes
so that the cluster is available.
The IP address of the loopback adapter is set in the dependencies
configuration.
#>
New-IntegrationLoopbackAdapter -AdapterName $mockLoopbackAdapterName

Describe "$($script:DSCResourceName)_Integration" {
BeforeAll {
$resourceId = "[$($script:DSCResourceFriendlyName)]Integration_Test"
Expand Down Expand Up @@ -61,7 +78,15 @@ try
ErrorAction = 'Stop'
}

Start-DscConfiguration @startDscConfigurationParameters
try
{
Start-DscConfiguration @startDscConfigurationParameters
}
catch
{
Write-Verbose -Message ('{0} {1}' -f $integrationErrorMessagePrefix, $_) -Verbose
throw $_
}
} | Should -Not -Throw
}
}
Expand Down Expand Up @@ -89,7 +114,15 @@ try
ErrorAction = 'Stop'
}

Start-DscConfiguration @startDscConfigurationParameters
try
{
Start-DscConfiguration @startDscConfigurationParameters
}
catch
{
Write-Verbose -Message ('{0} {1}' -f $integrationErrorMessagePrefix, $_) -Verbose
throw $_
}
} | Should -Not -Throw
}

Expand All @@ -115,14 +148,33 @@ try
Context ('When using configuration {0}' -f $configurationName) {
It 'Should compile and apply the MOF without throwing' {
{
# The variable $ConfigurationData was dot-sourced above.
& $configurationName `
-SqlInstallCredential $mockSqlInstallCredential `
-OutputPath $TestDrive `
-ConfigurationData $ConfigurationData

Start-DscConfiguration -Path $TestDrive `
-ComputerName localhost -Wait -Verbose -Force
$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'
}

try
{
Start-DscConfiguration @startDscConfigurationParameters
}
catch
{
Write-Verbose -Message ('{0} {1}' -f $integrationErrorMessagePrefix, $_) -Verbose
throw $_
}
} | Should -Not -Throw
}

Expand All @@ -142,6 +194,41 @@ try
$resourceCurrentState.IsHadrEnabled | Should -Be $false
}
}

$configurationName = "$($script:DSCResourceName)_CleanupDependencies_Config"

Context ('When using configuration {0}' -f $configurationName) {
It 'Should compile and apply the MOF without throwing' {
{
$configurationParameters = @{
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'
}

try
{
Start-DscConfiguration @startDscConfigurationParameters
}
catch
{
Write-Verbose -Message ('{0} {1}' -f $integrationErrorMessagePrefix, $_) -Verbose
throw $_
}
} | Should -Not -Throw
}
}
}
}
finally
Expand Down
94 changes: 76 additions & 18 deletions Tests/Integration/MSFT_SqlAlwaysOnService.config.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,27 @@
[Microsoft.DscResourceKit.IntegrationTest(OrderNumber = 2)]
param()

<#
Get all adapters with static IP addresses, all of which should be ignored
when creating the cluster.
#>
$ignoreAdapterIpAddress = Get-NetAdapter |
Get-NetIPInterface |
Where-Object -FilterScript {
$_.Dhcp -eq 'Disabled'
} | Get-NetIPAddress

$ignoreIpNetwork = @()
foreach ($adapterIpAddress in $ignoreAdapterIpAddress)
{
<#
Get-NetIPAddressNetwork is in CommonTestHelper.psm1 which is imported
withing the integration test before this file is dot-sourced.
#>
$ipNetwork = (Get-NetIPAddressNetwork -IPAddress $adapterIpAddress.IPAddress -PrefixLength $adapterIpAddress.PrefixLength).NetworkAddress
$ignoreIpNetwork += ('{0}/{1}' -f $ipNetwork, $adapterIpAddress.PrefixLength)
}

$ConfigurationData = @{
AllNodes = @(
@{
Expand All @@ -10,6 +31,13 @@ $ConfigurationData = @{
InstanceName = 'DSCSQL2016'
RestartTimeout = 120

LoopbackAdapterName = 'ClusterNetwork'
LoopbackAdapterIpAddress = '192.168.40.10'
LoopbackAdapterGateway = '192.168.40.254'

ClusterStaticIpAddress = '192.168.40.11'
IgnoreNetwork = $ignoreIpNetwork

PSDscAllowPlainTextPassword = $true
}
)
Expand All @@ -18,18 +46,39 @@ $ConfigurationData = @{
Configuration MSFT_SqlAlwaysOnService_CreateDependencies_Config
{
Import-DscResource -ModuleName 'PSDscResources'
Import-DscResource -ModuleName 'xNetworking'

node localhost {
node localhost
{
WindowsFeature 'AddFeatureFailoverClustering'
{
Ensure = "Present"
Name = "Failover-clustering"
Ensure = 'Present'
Name = 'Failover-clustering'
}

WindowsFeature 'AddFeatureFailoverClusteringPowerShellModule'
{
Ensure = "Present"
Name = "RSAT-Clustering-PowerShell"
Ensure = 'Present'
Name = 'RSAT-Clustering-PowerShell'
}

xIPAddress LoopbackAdapterIPv4Address
{
IPAddress = $Node.LoopbackAdapterIpAddress
InterfaceAlias = $Node.LoopbackAdapterName
AddressFamily = 'IPv4'
}

<#
Must have a default gateway for the Cluster to be able to use the
loopback adapter as clustered network.
This will be removed directly after the cluster has been created.
#>
xDefaultGatewayAddress LoopbackAdapterIPv4DefaultGateway
{
Address = $Node.LoopbackAdapterGateway
InterfaceAlias = $Node.LoopbackAdapterName
AddressFamily = 'IPv4'
}

<#
Expand All @@ -40,24 +89,16 @@ Configuration MSFT_SqlAlwaysOnService_CreateDependencies_Config
Script 'CreateActiveDirectoryDetachedCluster'
{
SetScript = {
<#
This is used to get the correct IP address in AppVeyor.
The logic is to get the IP address of the first NIC not
named something like 'Internal' and then addition 1 to the
last number. For example if the NIC has and IP address
of 10.0.0.10, then cluster IP address will be 10.0.0.11.
#>
$ipAddress = Get-NetIPConfiguration | Where-Object -FilterScript {
$_.InterfaceAlias -notlike '*Internal*'
} | Select-Object -ExpandProperty IPv4Address | Select-Object IPAddress
$ipAddressParts = ($ipAddress[0].IPAddress -split '\.')
[System.UInt32] $ipAddressParts[3] += 1
$clusterStaticIpAddress = ($ipAddressParts -join '.')
$clusterStaticIpAddress = $Using:Node.ClusterStaticIpAddress
$ignoreNetwork = $Using:Node.IgnoreNetwork

Write-Verbose -Message ('Ignoring networks: ''{0}''' -f ($ignoreNetwork -join ', ')) -Verbose

$newClusterParameters = @{
Name = 'DSCCLU01'
Node = $env:COMPUTERNAME
StaticAddress = $clusterStaticIpAddress
IgnoreNetwork = $ignoreNetwork
NoStorage = $true
AdministrativeAccessPoint = 'Dns'

Expand Down Expand Up @@ -125,6 +166,23 @@ Configuration MSFT_SqlAlwaysOnService_CreateDependencies_Config
}
}

Configuration MSFT_SqlAlwaysOnService_CleanupDependencies_Config
{
Import-DscResource -ModuleName 'xNetworking'

node localhost
{
<#
Removing the default gateway from the loopback adapter.
#>
xDefaultGatewayAddress LoopbackAdapterIPv4DefaultGateway
{
InterfaceAlias = $Node.LoopbackAdapterName
AddressFamily = 'IPv4'
}
}
}

Configuration MSFT_SqlAlwaysOnService_EnableAlwaysOn_Config
{
param
Expand Down
22 changes: 22 additions & 0 deletions Tests/Integration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,28 @@ sa | P@ssw0rd1 | Administrator of the Database Engine instances DSCSQL2016. |
with this user and that means that this user must have permission to access the
properties `IsClustered` and `IsHadrEnable`.*

## SqlAlwaysOnService

**Run order:** 2

**Depends on:** SqlSetup

The integration test will install a loopback adapter named 'ClusterNetwork' with
an IP address of '192.168.40.10'. To be able to activate the AlwaysOn service the
tests creates an Active Directory Detached Cluster with an IP address of
'192.168.40.11' and the cluster will ignore any other static IP addresses.

>**Note:** During the tests the gateway of the loopback adatper named 'ClusterNetwork'
>will be set to '192.168.40.254', because it is a requirement to create the cluster,
>but the gateway will be removed in the last clean up test. Gateway is removed so
>that there will be no conflict with the default gateway.
>*Note:** The Active Directory Detached Cluster is not fully functioning in the
>sense that it cannot start the Name resource in the 'Cluster Group', but it
>starts enough to be able to run integration tests for AlwaysOn service.s
The tests will leave the AlwaysOn service disabled.

## SqlRS

**Run order:** 2
Expand Down
Loading

0 comments on commit b2c3602

Please sign in to comment.