Skip to content

Commit 83aa428

Browse files
Copilotjohlju
andcommitted
Add integration test for Get-SqlDscDatabasePermission command
Co-authored-by: johlju <7189721+johlju@users.noreply.github.com>
1 parent c0cb0f5 commit 83aa428

File tree

4 files changed

+217
-0
lines changed

4 files changed

+217
-0
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
### Added
99

10+
- Added integration tests for `Get-SqlDscDatabasePermission` command to ensure
11+
database permission retrieval functions correctly in real environments
12+
[issue #2221](https://github.com/dsccommunity/SqlServerDsc/issues/2221).
1013
- Added integration tests for `Remove-SqlDscAudit` command to ensure it functions
1114
correctly in real environments
1215
[issue #2241](https://github.com/dsccommunity/SqlServerDsc/issues/2241).

azure-pipelines.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ stages:
313313
'tests/Integration/Commands/New-SqlDscDatabase.Integration.Tests.ps1'
314314
'tests/Integration/Commands/Set-SqlDscDatabase.Integration.Tests.ps1'
315315
'tests/Integration/Commands/Test-SqlDscDatabase.Integration.Tests.ps1'
316+
'tests/Integration/Commands/Get-SqlDscDatabasePermission.Integration.Tests.ps1'
316317
'tests/Integration/Commands/Get-SqlDscAgentAlert.Integration.Tests.ps1'
317318
'tests/Integration/Commands/New-SqlDscAgentAlert.Integration.Tests.ps1'
318319
'tests/Integration/Commands/Set-SqlDscAgentAlert.Integration.Tests.ps1'
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
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 build" first.'
23+
}
24+
}
25+
26+
BeforeAll {
27+
$script:moduleName = 'SqlServerDsc'
28+
29+
Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop'
30+
}
31+
32+
Describe 'Get-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
45+
46+
# Create a test database for the integration tests
47+
$script:testDatabaseName = 'SqlDscDatabasePermissionTest_' + (Get-Random)
48+
$null = New-SqlDscDatabase -ServerObject $script:serverObject -Name $script:testDatabaseName -Force -ErrorAction 'Stop'
49+
50+
# Create a test user in the database for permission testing
51+
$script:testUserName = 'SqlDscTestUser_' + (Get-Random)
52+
$testUserSql = "USE [$($script:testDatabaseName)]; CREATE USER [$($script:testUserName)] WITHOUT LOGIN;"
53+
Invoke-SqlDscQuery -ServerObject $script:serverObject -Database $script:testDatabaseName -Query $testUserSql -ErrorAction 'Stop'
54+
55+
# Grant some permissions to the test user for testing
56+
$grantPermissionSql = "USE [$($script:testDatabaseName)]; GRANT CONNECT, SELECT TO [$($script:testUserName)];"
57+
Invoke-SqlDscQuery -ServerObject $script:serverObject -Database $script:testDatabaseName -Query $grantPermissionSql -ErrorAction 'Stop'
58+
}
59+
60+
AfterAll {
61+
# Clean up test database (this will also remove the test user)
62+
$testDatabase = Get-SqlDscDatabase -ServerObject $script:serverObject -Name $script:testDatabaseName -ErrorAction 'SilentlyContinue'
63+
if ($testDatabase)
64+
{
65+
$null = Remove-SqlDscDatabase -DatabaseObject $testDatabase -Force -ErrorAction 'Stop'
66+
}
67+
68+
Disconnect-SqlDscDatabaseEngine -ServerObject $script:serverObject
69+
70+
# Stop the named instance SQL Server service to save memory on the build worker.
71+
Stop-Service -Name 'MSSQL$DSCSQLTEST' -Verbose -ErrorAction 'Stop'
72+
}
73+
74+
Context 'When connecting to SQL Server instance' {
75+
Context 'When getting permissions for valid database principals' {
76+
It 'Should return permissions for dbo user in master database' {
77+
$result = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName 'master' -Name 'dbo'
78+
79+
$result | Should -Not -BeNullOrEmpty
80+
$result | Should -BeOfType [Microsoft.SqlServer.Management.Smo.DatabasePermissionInfo]
81+
}
82+
83+
It 'Should return permissions for dbo user in master database using pipeline' {
84+
$result = $script:serverObject | Get-SqlDscDatabasePermission -DatabaseName 'master' -Name 'dbo'
85+
86+
$result | Should -Not -BeNullOrEmpty
87+
$result | Should -BeOfType [Microsoft.SqlServer.Management.Smo.DatabasePermissionInfo]
88+
}
89+
90+
It 'Should return permissions for public role in master database' {
91+
$result = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName 'master' -Name 'public'
92+
93+
$result | Should -Not -BeNullOrEmpty
94+
$result | Should -BeOfType [Microsoft.SqlServer.Management.Smo.DatabasePermissionInfo]
95+
}
96+
97+
It 'Should return permissions for test user in test database' {
98+
$result = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testUserName
99+
100+
$result | Should -Not -BeNullOrEmpty
101+
$result | Should -BeOfType [Microsoft.SqlServer.Management.Smo.DatabasePermissionInfo]
102+
103+
# Verify that the Connect and Select permissions we granted are present
104+
$connectPermission = $result | Where-Object { $_.PermissionType.Connect -eq $true }
105+
$selectPermission = $result | Where-Object { $_.PermissionType.Select -eq $true }
106+
107+
$connectPermission | Should -Not -BeNullOrEmpty -Because 'Connect permission should have been granted to test user'
108+
$connectPermission.PermissionState | Should -Be 'Grant'
109+
110+
$selectPermission | Should -Not -BeNullOrEmpty -Because 'Select permission should have been granted to test user'
111+
$selectPermission.PermissionState | Should -Be 'Grant'
112+
}
113+
}
114+
115+
Context 'When getting permissions for invalid principals' {
116+
It 'Should throw error for non-existent database with ErrorAction Stop' {
117+
{ Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName 'NonExistentDatabase123' -Name 'dbo' -ErrorAction 'Stop' } |
118+
Should -Throw
119+
}
120+
121+
It 'Should return null for non-existent database with ErrorAction SilentlyContinue' {
122+
$result = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName 'NonExistentDatabase123' -Name 'dbo' -ErrorAction 'SilentlyContinue'
123+
124+
$result | Should -BeNullOrEmpty
125+
}
126+
127+
It 'Should throw error for non-existent principal with ErrorAction Stop' {
128+
{ Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName 'master' -Name 'NonExistentUser123' -ErrorAction 'Stop' } |
129+
Should -Throw
130+
}
131+
132+
It 'Should return null for non-existent principal with ErrorAction SilentlyContinue' {
133+
$result = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName 'master' -Name 'NonExistentUser123' -ErrorAction 'SilentlyContinue'
134+
135+
$result | Should -BeNullOrEmpty
136+
}
137+
}
138+
139+
Context 'When verifying permission properties' {
140+
BeforeAll {
141+
# Get permissions for a known principal that should have permissions
142+
$script:testPermissions = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $script:testUserName
143+
}
144+
145+
It 'Should return DatabasePermissionInfo objects with PermissionState property' {
146+
$script:testPermissions | Should -Not -BeNullOrEmpty
147+
148+
foreach ($permission in $script:testPermissions) {
149+
$permission.PermissionState | Should -BeIn @('Grant', 'Deny', 'GrantWithGrant')
150+
}
151+
}
152+
153+
It 'Should return DatabasePermissionInfo objects with PermissionType property' {
154+
$script:testPermissions | Should -Not -BeNullOrEmpty
155+
156+
foreach ($permission in $script:testPermissions) {
157+
$permission.PermissionType | Should -Not -BeNullOrEmpty
158+
$permission.PermissionType | Should -BeOfType [Microsoft.SqlServer.Management.Smo.DatabasePermissionSet]
159+
}
160+
}
161+
162+
It 'Should return DatabasePermissionInfo objects with Grantee property' {
163+
$script:testPermissions | Should -Not -BeNullOrEmpty
164+
165+
foreach ($permission in $script:testPermissions) {
166+
$permission.Grantee | Should -Be $script:testUserName
167+
}
168+
}
169+
}
170+
171+
Context 'When working with built-in database roles' {
172+
It 'Should return permissions for db_datareader role' {
173+
# Note: The command excludes fixed roles by default, so this should return null or empty
174+
$result = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name 'db_datareader' -ErrorAction 'SilentlyContinue'
175+
176+
# Fixed roles are excluded by default, so result should be null
177+
$result | Should -BeNullOrEmpty
178+
}
179+
180+
It 'Should work with non-fixed database roles when they exist' {
181+
# Create a custom database role for testing
182+
$customRoleName = 'TestRole_' + (Get-Random)
183+
$createRoleSql = "USE [$($script:testDatabaseName)]; CREATE ROLE [$customRoleName];"
184+
Invoke-SqlDscQuery -ServerObject $script:serverObject -Database $script:testDatabaseName -Query $createRoleSql -ErrorAction 'Stop'
185+
186+
try
187+
{
188+
# Grant a permission to the custom role
189+
$grantRolePermissionSql = "USE [$($script:testDatabaseName)]; GRANT CONNECT TO [$customRoleName];"
190+
Invoke-SqlDscQuery -ServerObject $script:serverObject -Database $script:testDatabaseName -Query $grantRolePermissionSql -ErrorAction 'Stop'
191+
192+
# Test getting permissions for the custom role
193+
$result = Get-SqlDscDatabasePermission -ServerObject $script:serverObject -DatabaseName $script:testDatabaseName -Name $customRoleName
194+
195+
$result | Should -Not -BeNullOrEmpty
196+
$result | Should -BeOfType [Microsoft.SqlServer.Management.Smo.DatabasePermissionInfo]
197+
198+
# Verify the Connect permission we granted is present
199+
$connectPermission = $result | Where-Object { $_.PermissionType.Connect -eq $true }
200+
$connectPermission | Should -Not -BeNullOrEmpty
201+
$connectPermission.PermissionState | Should -Be 'Grant'
202+
}
203+
finally
204+
{
205+
# Clean up the custom role
206+
$dropRoleSql = "USE [$($script:testDatabaseName)]; DROP ROLE [$customRoleName];"
207+
Invoke-SqlDscQuery -ServerObject $script:serverObject -Database $script:testDatabaseName -Query $dropRoleSql -ErrorAction 'SilentlyContinue'
208+
}
209+
}
210+
}
211+
}
212+
}

tests/Integration/Commands/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ Get-SqlDscDatabase | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTES
6565
New-SqlDscDatabase | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | Test databases
6666
Set-SqlDscDatabase | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
6767
Test-SqlDscDatabase | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
68+
Get-SqlDscDatabasePermission | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | Test database, Test user
6869
Get-SqlDscAgentAlert | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
6970
New-SqlDscAgentAlert | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | Test alerts
7071
Set-SqlDscAgentAlert | 2 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -

0 commit comments

Comments
 (0)