Skip to content

Commit

Permalink
xSQLServerMemory: Make Cluster Aware (#896)
Browse files Browse the repository at this point in the history
- Changes to xSQLServerMemory
  - Made the resource cluster aware. When ProcessOnlyOnActiveNode is specified,
    the resource will only determine if a change is needed if the target node
    is the active host of the SQL Server instance (issue #867).
  • Loading branch information
randomnote1 authored and johlju committed Oct 31, 2017
1 parent 88bcd27 commit 61862e7
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 32 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
- Added the CommonTestHelper.psm1 to store common testing functions.
- Added the Import-SQLModuleStub function to ensure the correct version of the
module stubs are loaded ([issue #784](https://github.com/PowerShell/xSQLServer/issues/784)).
- Changes to xSQLServerMemory
- Made the resource cluster aware. When ProcessOnlyOnActiveNode is specified,
the resource will only determine if a change is needed if the target node
is the active host of the SQL Server instance ([issue #867](https://github.com/PowerShell/xSQLServer/issues/867)).
- Changes to xSQLServerNetwork
- BREAKING CHANGE: Renamed parameter TcpDynamicPorts to TcpDynamicPort and
changed type to Boolean ([issue #534](https://github.com/PowerShell/xSQLServer/issues/534)).
Expand Down
76 changes: 53 additions & 23 deletions DSCResources/MSFT_xSQLServerMemory/MSFT_xSQLServerMemory.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Pare

<#
.SYNOPSIS
This function gets the value of the min and max memory server configuration option.
This function gets the value of the min and max memory server configuration option.
.PARAMETER SQLServer
The host name of the SQL Server to be configured.
The host name of the SQL Server to be configured.
.PARAMETER SQLInstanceName
The name of the SQL instance to be configured.
The name of the SQL instance to be configured.
#>

function Get-TargetResource
Expand All @@ -35,41 +35,49 @@ function Get-TargetResource
Write-Verbose -Message 'Getting the value for minimum and maximum SQL server memory.'
$minMemory = $sqlServerObject.Configuration.MinServerMemory.ConfigValue
$maxMemory = $sqlServerObject.Configuration.MaxServerMemory.ConfigValue

# Is this node actively hosting the SQL instance?
$isActiveNode = Test-ActiveNode -ServerObject $sqlServerObject
}

$returnValue = @{
SQLInstanceName = $SQLInstanceName
SQLServer = $SQLServer
MinMemory = $minMemory
MaxMemory = $maxMemory
IsActiveNode = $isActiveNode
}

$returnValue
}

<#
.SYNOPSIS
This function sets the value for the min and max memory server configuration option.
This function sets the value for the min and max memory server configuration option.
.PARAMETER SQLServer
The host name of the SQL Server to be configured.
The host name of the SQL Server to be configured.
.PARAMETER SQLInstanceName
The name of the SQL instance to be configured.
The name of the SQL instance to be configured.
.PARAMETER Ensure
When set to 'Present' then min and max memory will be set to either the value in parameter MinMemory and MaxMemory or dynamically configured when parameter DynamicAlloc is set to $true.
When set to 'Absent' min and max memory will be set to default values.
When set to 'Present' then min and max memory will be set to either the value in parameter MinMemory and MaxMemory or dynamically configured when parameter DynamicAlloc is set to $true.
When set to 'Absent' min and max memory will be set to default values.
.PARAMETER DynamicAlloc
If set to $true then max memory will be dynamically configured.
When this is set parameter is set to $true, the parameter MaxMemory must be set to $null or not be configured.
If set to $true then max memory will be dynamically configured.
When this is set parameter is set to $true, the parameter MaxMemory must be set to $null or not be configured.
.PARAMETER MinMemory
This is the minimum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.
This is the minimum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.
.PARAMETER MaxMemory
This is the maximum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.
This is the maximum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.
.PARAMETER ProcessOnlyOnActiveNode
Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server instance.
Not used in Set-TargetResource.
#>
function Set-TargetResource
{
Expand Down Expand Up @@ -101,7 +109,11 @@ function Set-TargetResource

[Parameter()]
[System.Int32]
$MaxMemory
$MaxMemory,

[Parameter()]
[Boolean]
$ProcessOnlyOnActiveNode
)

$sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName
Expand Down Expand Up @@ -170,27 +182,30 @@ function Set-TargetResource

<#
.SYNOPSIS
This function tests the value of the min and max memory server configuration option.
This function tests the value of the min and max memory server configuration option.
.PARAMETER SQLServer
The host name of the SQL Server to be configured.
The host name of the SQL Server to be configured.
.PARAMETER SQLInstanceName
The name of the SQL instance to be configured.
The name of the SQL instance to be configured.
.PARAMETER Ensure
When set to 'Present' then min and max memory will be set to either the value in parameter MinMemory and MaxMemory or dynamically configured when parameter DynamicAlloc is set to $true.
When set to 'Absent' min and max memory will be set to default values.
When set to 'Present' then min and max memory will be set to either the value in parameter MinMemory and MaxMemory or dynamically configured when parameter DynamicAlloc is set to $true.
When set to 'Absent' min and max memory will be set to default values.
.PARAMETER DynamicAlloc
If set to $true then max memory will be dynamically configured.
When this is set parameter is set to $true, the parameter MaxMemory must be set to $null or not be configured.
If set to $true then max memory will be dynamically configured.
When this is set parameter is set to $true, the parameter MaxMemory must be set to $null or not be configured.
.PARAMETER MinMemory
This is the minimum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.
This is the minimum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.
.PARAMETER MaxMemory
This is the maximum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.
This is the maximum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.
.PARAMETER ProcessOnlyOnActiveNode
Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server instance.
#>
function Test-TargetResource
{
Expand Down Expand Up @@ -223,7 +238,11 @@ function Test-TargetResource

[Parameter()]
[System.Int32]
$MaxMemory
$MaxMemory,

[Parameter()]
[Boolean]
$ProcessOnlyOnActiveNode
)

Write-Verbose -Message 'Testing the values of the minimum and maximum memory server configuration option set to be used by the instance.'
Expand All @@ -239,6 +258,17 @@ function Test-TargetResource
$currentMaxMemory = $getTargetResourceResult.MaxMemory
$isServerMemoryInDesiredState = $true

<#
If this is supposed to process only the active node, and this is not the
active node, don't bother evaluating the test.
#>
if ( $ProcessOnlyOnActiveNode -and -not $getTargetResourceResult.IsActiveNode )
{
# Use localization if the resource has been converted
New-VerboseMessage -Message ( 'The node "{0}" is not actively hosting the instance "{1}". Exiting the test.' -f $env:COMPUTERNAME,$SQLInstanceName )
return $isServerMemoryInDesiredState
}

switch ($Ensure)
{
'Absent'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ class MSFT_xSQLServerMemory : OMI_BaseResource
[Write, Description("If set to $true then max memory will be dynamically configured. When this is set parameter is set to $true, the parameter MaxMemory must be set to $null or not be configured. Default value is $false.")] Boolean DynamicAlloc;
[Write, Description("Minimum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.")] Sint32 MinMemory;
[Write, Description("Maximum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.")] Sint32 MaxMemory;
[Write, Description("Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server instance.")] Boolean ProcessOnlyOnActiveNode;
[Read, Description("Determines if the current node is actively hosting the SQL Server instance.")] Boolean IsActiveNode;
};
16 changes: 11 additions & 5 deletions Examples/Resources/xSQLServerMemory/2-SetMaxMemoryToAuto.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
.EXAMPLE
This example shows how to set the maximum memory
configuration option with the automatic configuration.
In the event this is applied to a Failover Cluster Instance (FCI), the
ProcessOnlyOnActiveNode property will tell the Test-TargetResource function
to evaluate if any changes are needed if the node is actively hosting the
SQL Server instance.
#>
Configuration Example
{
Expand All @@ -19,11 +24,12 @@ Configuration Example
{
xSQLServerMemory Set_SQLServerMaxMemory_ToAuto
{
Ensure = 'Present'
DynamicAlloc = $true
SQLServer = 'SQLServer'
SQLInstanceName = 'DSC'
PsDscRunAsCredential = $SysAdminAccount
Ensure = 'Present'
DynamicAlloc = $true
SQLServer = 'SQLServer'
SQLInstanceName = 'DSC'
PsDscRunAsCredential = $SysAdminAccount
ProcessOnlyOnActiveNode = $true
}
}
}
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,14 @@ SQL Max Memory = TotalPhysicalMemory - (NumOfSQLThreads\*ThreadStackSize) -
pool used by the instance of SQL Server.
* **`[Sint32]` MaxMemory** _(Write)_: Maximum amount of memory, in MB, in the buffer
pool used by the instance of SQL Server.
* **`[Boolean]` ProcessOnlyOnActiveNode** _(Write)_: Specifies that the resource
will only determine if a change is needed if the target node is the active
host of the SQL Server instance.

#### Read-Only Properties from Get-TargetResource

* **`[Boolean]` IsActiveNode** _(Read)_: Determines if the current node is
actively hosting the SQL Server instance.

#### Examples

Expand Down
64 changes: 60 additions & 4 deletions Tests/Unit/MSFT_xSQLServerMemory.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ if ( (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCR

Import-Module (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force

# Loading mocked classes
Add-Type -Path ( Join-Path -Path ( Join-Path -Path $PSScriptRoot -ChildPath Stubs ) -ChildPath SMO.cs )

$TestEnvironment = Initialize-TestEnvironment `
-DSCModuleName $script:DSCModuleName `
-DSCResourceName $script:DSCResourceName `
Expand Down Expand Up @@ -40,6 +43,7 @@ try
$mockPhysicalMemoryCapacity = 8589934592
$mockExpectedMinMemoryForAlterMethod = 0
$mockExpectedMaxMemoryForAlterMethod = 2147483647
$mockTestActiveNode = $true

# Default parameters that are used for the It-blocks
$mockDefaultParameters = @{
Expand All @@ -52,9 +56,10 @@ try
$mockConnectSQL = {
return @(
(
New-Object Object |
Add-Member -MemberType NoteProperty -Name InstanceName -Value $mockSQLServerInstanceName -PassThru |
Add-Member -MemberType NoteProperty -Name ComputerNamePhysicalNetBIOS -Value $mockSQLServerName -PassThru |
# New-Object Object |
New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server |
Add-Member -MemberType NoteProperty -Name InstanceName -Value $mockSQLServerInstanceName -PassThru -Force |
Add-Member -MemberType NoteProperty -Name ComputerNamePhysicalNetBIOS -Value $mockSQLServerName -PassThru -Force |
Add-Member -MemberType ScriptProperty -Name Configuration -Value {
return @( ( New-Object Object |
Add-Member -MemberType ScriptProperty -Name MinServerMemory -Value {
Expand All @@ -74,7 +79,7 @@ try
) )
} -PassThru -Force
) )
} -PassThru |
} -PassThru -Force |
Add-Member -MemberType ScriptMethod -Name Alter -Value {
if ( $this.Configuration.MinServerMemory.ConfigValue -ne $mockExpectedMinMemoryForAlterMethod )
{
Expand All @@ -93,6 +98,7 @@ try

Describe "MSFT_xSQLServerMemory\Get-TargetResource" -Tag 'Get'{
Mock -CommandName Connect-SQL -MockWith $mockConnectSQL -Verifiable
Mock -CommandName Test-ActiveNode -MockWith { return $mockTestActiveNode } -Verifiable

Context 'When the system is either in the desired state or not in the desired state' {
$testParameters = $mockDefaultParameters
Expand All @@ -115,6 +121,10 @@ try
It 'Should call the mock function Connect-SQL' {
Assert-MockCalled Connect-SQL -Exactly -Times 1 -Scope Context
}

It 'Should call the mock function Test-ActiveNode' {
Assert-MockCalled Test-ActiveNode -Exactly -Times 1 -Scope Context
}
}

Assert-VerifiableMock
Expand Down Expand Up @@ -161,6 +171,8 @@ try
$mockGetCimInstanceOS
} -ParameterFilter { $ClassName -eq 'Win32_operatingsystem' } -Verifiable

Mock -CommandName Test-ActiveNode -MockWith { return $mockTestActiveNode } -Verifiable

Context 'When the system is not in the desired state and DynamicAlloc is set to false' {
$testParameters = $mockDefaultParameters
$testParameters += @{
Expand Down Expand Up @@ -305,6 +317,50 @@ try
}
}

Context 'When the system is not in the desired state, DynamicAlloc is set to true and ProcessOnlyOnActiveNode is set to true' {
AfterAll {
$mockTestActiveNode = $true
}

BeforeAll {
$testParameters = $mockDefaultParameters
$testParameters += @{
Ensure = 'Present'
DynamicAlloc = $true
ProcessOnlyOnActiveNode = $true
}

$mockTestActiveNode = $false
}

It 'Should return the state as true' {
$result = Test-TargetResource @testParameters
$result | Should -Be $true
}

It 'Should call the mock function Connect-SQL' {
Assert-MockCalled Connect-SQL -Exactly -Times 1 -Scope Context
}

It 'Should not call the mock function Get-CimInstance with ClassName equal to Win32_PhysicalMemory' {
Assert-MockCalled Get-CimInstance -Exactly -Times 0 -ParameterFilter {
$ClassName -eq 'Win32_PhysicalMemory'
} -Scope Context
}

It 'Should not call the mock function Get-CimInstance with ClassName equal to Win32_Processor' {
Assert-MockCalled Get-CimInstance -Exactly -Times 0 -ParameterFilter {
$ClassName -eq 'Win32_Processor'
} -Scope Context
}

It 'Should not call the mock function Get-CimInstance with ClassName equal to Win32_operatingsystem' {
Assert-MockCalled Get-CimInstance -Exactly -Times 0 -ParameterFilter {
$ClassName -eq 'Win32_operatingsystem'
} -Scope Context
}
}

$mockMinServerMemory = 0
$mockMaxServerMemory = 12083

Expand Down

0 comments on commit 61862e7

Please sign in to comment.