Skip to content

Commit f316f18

Browse files
authored
Add integration test for Set-SqlDscDatabasePermission (#2266)
1 parent 3a0bfd0 commit f316f18

File tree

4 files changed

+279
-0
lines changed

4 files changed

+279
-0
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3434
- Added integration tests for `ConvertTo-SqlDscDatabasePermission` command to
3535
ensure command reliability
3636
[issue #2209](https://github.com/dsccommunity/SqlServerDsc/issues/2209).
37+
- Added integration tests for `Set-SqlDscDatabasePermission` command to ensure
38+
command reliability
39+
[issue #2235](https://github.com/dsccommunity/SqlServerDsc/issues/2235).
3740
- Added integration test for `ConvertTo-SqlDscEditionName` command to ensure
3841
command reliability in real environments
3942
[issue #2208](https://github.com/dsccommunity/SqlServerDsc/issues/2208).

azure-pipelines.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ stages:
325325
'tests/Integration/Commands/New-SqlDscDatabase.Integration.Tests.ps1'
326326
'tests/Integration/Commands/Set-SqlDscDatabase.Integration.Tests.ps1'
327327
'tests/Integration/Commands/Test-SqlDscDatabase.Integration.Tests.ps1'
328+
'tests/Integration/Commands/Set-SqlDscDatabasePermission.Integration.Tests.ps1'
328329
'tests/Integration/Commands/ConvertTo-SqlDscDatabasePermission.Integration.Tests.ps1'
329330
'tests/Integration/Commands/Get-SqlDscAgentAlert.Integration.Tests.ps1'
330331
'tests/Integration/Commands/New-SqlDscAgentAlert.Integration.Tests.ps1'

tests/Integration/Commands/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ New-SqlDscDatabase | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTES
7979
Set-SqlDscDatabase | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
8080
Test-SqlDscDatabase | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
8181
ConvertTo-SqlDscDatabasePermission | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
82+
Set-SqlDscDatabasePermission | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
8283
Get-SqlDscAgentAlert | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
8384
New-SqlDscAgentAlert | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | Test alerts
8485
Set-SqlDscAgentAlert | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')]
2+
param ()
3+
4+
BeforeDiscovery {
5+
try
6+
{
7+
if (-not (Get-Module -Name 'DscResource.Test'))
8+
{
9+
# Assumes dependencies have been resolved, so if this module is not available, run 'noop' task.
10+
if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable))
11+
{
12+
# Redirect all streams to $null, except the error stream (stream 2)
13+
& "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 3>&1 4>&1 5>&1 6>&1 > $null
14+
}
15+
16+
# If the dependencies have not been resolved, this will throw an error.
17+
Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop'
18+
}
19+
}
20+
catch [System.IO.FileNotFoundException]
21+
{
22+
throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks noop" first.'
23+
}
24+
}
25+
26+
BeforeAll {
27+
$script:moduleName = 'SqlServerDsc'
28+
29+
Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop'
30+
}
31+
32+
Describe 'Set-SqlDscDatabasePermission' -Tag @('Integration_SQL2017', 'Integration_SQL2019', 'Integration_SQL2022') {
33+
BeforeAll {
34+
# Starting the named instance SQL Server service prior to running tests.
35+
Start-Service -Name 'MSSQL$DSCSQLTEST' -Verbose -ErrorAction 'Stop'
36+
37+
$script:mockInstanceName = 'DSCSQLTEST'
38+
39+
$mockSqlAdministratorUserName = 'SqlAdmin' # Using computer name as NetBIOS name throw exception.
40+
$mockSqlAdministratorPassword = ConvertTo-SecureString -String 'P@ssw0rd1' -AsPlainText -Force
41+
42+
$script:mockSqlAdminCredential = [System.Management.Automation.PSCredential]::new($mockSqlAdministratorUserName, $mockSqlAdministratorPassword)
43+
44+
$script:serverObject = Connect-SqlDscDatabaseEngine -InstanceName $script:mockInstanceName -Credential $script:mockSqlAdminCredential -ErrorAction 'Stop'
45+
46+
# Use existing persistent test database from New-SqlDscDatabase integration tests
47+
$script:testDatabaseName = 'SqlDscIntegrationTestDatabase'
48+
49+
# Use existing persistent principals created by earlier integration tests
50+
$script:testLoginName = 'IntegrationTestSqlLogin'
51+
$script:testRoleName = 'SqlDscIntegrationTestRole_Persistent'
52+
53+
# Ensure the test database exists
54+
$existingDatabase = Get-SqlDscDatabase -ServerObject $script:serverObject -Name $script:testDatabaseName -ErrorAction 'SilentlyContinue'
55+
56+
if (-not $existingDatabase)
57+
{
58+
$null = New-SqlDscDatabase -ServerObject $script:serverObject -Name $script:testDatabaseName -Force -ErrorAction 'Stop'
59+
}
60+
61+
# Create a database user for the existing login for testing database permissions
62+
$sqlQuery = @"
63+
USE [$script:testDatabaseName];
64+
IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = '$script:testLoginName')
65+
BEGIN
66+
CREATE USER [$script:testLoginName] FOR LOGIN [$script:testLoginName];
67+
END
68+
"@
69+
$null = Invoke-SqlDscQuery -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Query $sqlQuery -Force -ErrorAction 'Stop'
70+
}
71+
72+
AfterAll {
73+
# Clean up test database user but leave database intact for other tests
74+
$sqlQuery = @"
75+
USE [$script:testDatabaseName];
76+
IF EXISTS (SELECT * FROM sys.database_principals WHERE name = '$script:testLoginName')
77+
BEGIN
78+
DROP USER [$script:testLoginName];
79+
END
80+
"@
81+
$null = Invoke-SqlDscQuery -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Query $sqlQuery -Force -ErrorAction 'SilentlyContinue'
82+
83+
Disconnect-SqlDscDatabaseEngine -ServerObject $script:serverObject
84+
85+
# Stop the named instance SQL Server service to save memory on the build worker.
86+
Stop-Service -Name 'MSSQL$DSCSQLTEST' -Verbose -ErrorAction 'Stop'
87+
}
88+
89+
Context 'When setting database permissions with Grant state' {
90+
BeforeEach {
91+
# Revoke any existing permissions to start with clean state
92+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
93+
Connect = $true
94+
}
95+
$null = Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -State 'Revoke' -Permission $permissionSet -Force -ErrorAction 'SilentlyContinue'
96+
97+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
98+
Select = $true
99+
}
100+
$null = Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -State 'Revoke' -Permission $permissionSet -Force -ErrorAction 'SilentlyContinue'
101+
}
102+
103+
It 'Should grant Connect permission successfully' {
104+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
105+
Connect = $true
106+
}
107+
108+
$null = Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -State 'Grant' -Permission $permissionSet -Force -ErrorAction 'Stop'
109+
110+
# Verify the permission was granted
111+
$permissions = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -ErrorAction 'Stop'
112+
113+
$permissions | Should -Not -BeNullOrEmpty
114+
$grantedPermission = $permissions | Where-Object { $_.PermissionState -eq 'Grant' -and $_.PermissionType.Connect -eq $true }
115+
$grantedPermission | Should -Not -BeNullOrEmpty
116+
$grantedPermission.PermissionType.Connect | Should -BeTrue
117+
}
118+
119+
It 'Should grant multiple permissions successfully' {
120+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
121+
Connect = $true
122+
Select = $true
123+
}
124+
125+
$null = Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -State 'Grant' -Permission $permissionSet -Force -ErrorAction 'Stop'
126+
127+
# Verify the permissions were granted
128+
$permissions = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -ErrorAction 'Stop'
129+
130+
$permissions | Should -Not -BeNullOrEmpty
131+
132+
$connectPermission = $permissions | Where-Object { $_.PermissionState -eq 'Grant' -and $_.PermissionType.Connect -eq $true }
133+
$connectPermission | Should -Not -BeNullOrEmpty
134+
$connectPermission.PermissionType.Connect | Should -BeTrue
135+
136+
$selectPermission = $permissions | Where-Object { $_.PermissionState -eq 'Grant' -and $_.PermissionType.Select -eq $true }
137+
$selectPermission | Should -Not -BeNullOrEmpty
138+
$selectPermission.PermissionType.Select | Should -BeTrue
139+
}
140+
141+
It 'Should grant permissions with WithGrant option' {
142+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
143+
Select = $true
144+
}
145+
146+
$null = Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -State 'Grant' -Permission $permissionSet -WithGrant -Force -ErrorAction 'Stop'
147+
148+
# Verify the permission was granted with grant option
149+
$permissions = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -ErrorAction 'Stop'
150+
151+
$permissions | Should -Not -BeNullOrEmpty
152+
$grantedPermission = $permissions | Where-Object { $_.PermissionState -eq 'GrantWithGrant' -and $_.PermissionType.Select -eq $true }
153+
$grantedPermission | Should -Not -BeNullOrEmpty
154+
$grantedPermission.PermissionType.Select | Should -BeTrue
155+
}
156+
}
157+
158+
Context 'When setting database permissions with Deny state' {
159+
BeforeEach {
160+
# Start with clean state
161+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
162+
Update = $true
163+
}
164+
$null = Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -State 'Revoke' -Permission $permissionSet -Force -ErrorAction 'SilentlyContinue'
165+
}
166+
167+
It 'Should deny Update permission successfully' {
168+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
169+
Update = $true
170+
}
171+
172+
$null = Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -State 'Deny' -Permission $permissionSet -Force -ErrorAction 'Stop'
173+
174+
# Verify the permission was denied
175+
$permissions = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -ErrorAction 'Stop'
176+
177+
$permissions | Should -Not -BeNullOrEmpty
178+
$deniedPermission = $permissions | Where-Object { $_.PermissionState -eq 'Deny' -and $_.PermissionType.Update -eq $true }
179+
$deniedPermission | Should -Not -BeNullOrEmpty
180+
$deniedPermission.PermissionType.Update | Should -BeTrue
181+
}
182+
}
183+
184+
Context 'When setting database permissions with Revoke state' {
185+
BeforeEach {
186+
# Grant a permission first to then revoke it
187+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
188+
Insert = $true
189+
}
190+
$null = Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -State 'Grant' -Permission $permissionSet -Force -ErrorAction 'Stop'
191+
}
192+
193+
It 'Should revoke Insert permission successfully' {
194+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
195+
Insert = $true
196+
}
197+
198+
$null = Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -State 'Revoke' -Permission $permissionSet -Force -ErrorAction 'Stop'
199+
200+
# Verify the permission was revoked (should not appear in granted permissions)
201+
$permissions = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -ErrorAction 'Stop'
202+
203+
if ($permissions)
204+
{
205+
$insertPermission = $permissions | Where-Object { $_.PermissionType.Insert -eq $true }
206+
$insertPermission | Should -BeNullOrEmpty
207+
}
208+
}
209+
210+
It 'Should revoke permissions with WithGrant option to cascade revocation' {
211+
# First grant with grant option
212+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
213+
Delete = $true
214+
}
215+
$null = Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -State 'Grant' -Permission $permissionSet -WithGrant -Force -ErrorAction 'Stop'
216+
217+
# Then revoke with WithGrant to cascade
218+
$null = Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -State 'Revoke' -Permission $permissionSet -WithGrant -Force -ErrorAction 'Stop'
219+
220+
# Verify the permission was revoked (should not appear in permissions)
221+
$permissions = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -ErrorAction 'Stop'
222+
223+
if ($permissions)
224+
{
225+
$deletePermission = $permissions | Where-Object { $_.PermissionType.Delete -eq $true }
226+
$deletePermission | Should -BeNullOrEmpty
227+
}
228+
}
229+
}
230+
231+
Context 'When setting database permissions through pipeline' {
232+
BeforeEach {
233+
# Clean state
234+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
235+
Execute = $true
236+
}
237+
$null = Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -State 'Revoke' -Permission $permissionSet -Force -ErrorAction 'SilentlyContinue'
238+
}
239+
240+
It 'Should accept ServerObject from pipeline' {
241+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
242+
Execute = $true
243+
}
244+
245+
$null = $script:serverObject | Set-SqlDscDatabasePermission -DatabaseName $script:testDatabaseName -Name $script:testLoginName -State 'Grant' -Permission $permissionSet -Force -ErrorAction 'Stop'
246+
247+
# Verify the permission was granted
248+
$permissions = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testLoginName -ErrorAction 'Stop'
249+
250+
$permissions | Should -Not -BeNullOrEmpty
251+
$grantedPermission = $permissions | Where-Object { $_.PermissionState -eq 'Grant' -and $_.PermissionType.Execute -eq $true }
252+
$grantedPermission | Should -Not -BeNullOrEmpty
253+
$grantedPermission.PermissionType.Execute | Should -BeTrue
254+
}
255+
}
256+
257+
Context 'When setting database permissions with error conditions' {
258+
It 'Should throw an error when database does not exist' {
259+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
260+
Connect = $true
261+
}
262+
263+
{ Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName 'NonExistentDatabase' -Name $script:testLoginName -State 'Grant' -Permission $permissionSet -Force -ErrorAction 'Stop' } | Should -Throw -ExpectedMessage '*database*'
264+
}
265+
266+
It 'Should throw an error when database principal does not exist' {
267+
$permissionSet = [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet] @{
268+
Connect = $true
269+
}
270+
271+
{ Set-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name 'NonExistentPrincipal' -State 'Grant' -Permission $permissionSet -Force -ErrorAction 'Stop' } | Should -Throw -ExpectedMessage '*principal*'
272+
}
273+
}
274+
}

0 commit comments

Comments
 (0)