3
3
4
4
Describe ' WindowsPowerShell adapter resource tests - requires elevated permissions' {
5
5
6
- BeforeAll {
7
- if ($isWindows ) {
8
- winrm quickconfig - quiet - force
9
- }
10
- $OldPSModulePath = $env: PSModulePath
11
- $env: PSModulePath += [System.IO.Path ]::PathSeparator + $PSScriptRoot
12
-
13
- $winpsConfigPath = Join-path $PSScriptRoot " winps_resource.dsc.yaml"
14
- if ($isWindows ) {
15
- $cacheFilePath_v5 = Join-Path $env: LocalAppData " dsc" " WindowsPSAdapterCache.json"
16
- }
6
+ BeforeAll {
7
+ if ($isWindows ) {
8
+ winrm quickconfig - quiet - force
17
9
}
18
- AfterAll {
19
- $env: PSModulePath = $OldPSModulePath
10
+ $OldPSModulePath = $env: PSModulePath
11
+ $env: PSModulePath += [System.IO.Path ]::PathSeparator + $PSScriptRoot
12
+
13
+ $winpsConfigPath = Join-path $PSScriptRoot " winps_resource.dsc.yaml"
14
+ if ($isWindows ) {
15
+ $cacheFilePath_v5 = Join-Path $env: LocalAppData " dsc" " WindowsPSAdapterCache.json"
20
16
}
17
+ }
18
+ AfterAll {
19
+ $env: PSModulePath = $OldPSModulePath
20
+ }
21
21
22
- BeforeEach {
23
- if ($isWindows ) {
24
- Remove-Item - Force - ea SilentlyContinue - Path $cacheFilePath_v5
25
- }
22
+ BeforeEach {
23
+ if ($isWindows ) {
24
+ Remove-Item - Force - ea SilentlyContinue - Path $cacheFilePath_v5
26
25
}
26
+ }
27
27
28
- It ' Windows PowerShell adapter supports File resource' - Skip:(! $IsWindows ){
28
+ It ' Windows PowerShell adapter supports File resource' - Skip:(! $IsWindows ) {
29
29
30
- $r = dsc resource list -- adapter Microsoft.Windows/ WindowsPowerShell
31
- $LASTEXITCODE | Should - Be 0
32
- $resources = $r | ConvertFrom-Json
33
- ($resources | Where-Object {$_.Type -eq ' PSDesiredStateConfiguration/File' }).Count | Should - Be 1
34
- }
30
+ $r = dsc resource list -- adapter Microsoft.Windows/ WindowsPowerShell
31
+ $LASTEXITCODE | Should - Be 0
32
+ $resources = $r | ConvertFrom-Json
33
+ ($resources | Where-Object { $_.Type -eq ' PSDesiredStateConfiguration/File' }).Count | Should - Be 1
34
+ }
35
35
36
- It ' Get works on Binary "File" resource' - Skip:(! $IsWindows ){
36
+ It ' Get works on Binary "File" resource' - Skip:(! $IsWindows ) {
37
37
38
- $testFile = " $testdrive \test.txt"
39
- ' test' | Set-Content - Path $testFile - Force
40
- $r = ' {"DestinationPath":"' + $testFile.replace (' \' , ' \\' ) + ' "}' | dsc resource get - r ' PSDesiredStateConfiguration/File' -f -
41
- $LASTEXITCODE | Should - Be 0
42
- $res = $r | ConvertFrom-Json
43
- $res.actualState.DestinationPath | Should - Be " $testFile "
44
- }
38
+ $testFile = " $testdrive \test.txt"
39
+ ' test' | Set-Content - Path $testFile - Force
40
+ $r = ' {"DestinationPath":"' + $testFile.replace (' \' , ' \\' ) + ' "}' | dsc resource get - r ' PSDesiredStateConfiguration/File' -f -
41
+ $LASTEXITCODE | Should - Be 0
42
+ $res = $r | ConvertFrom-Json
43
+ $res.actualState.DestinationPath | Should - Be " $testFile "
44
+ }
45
45
46
- It ' Set works on Binary "File" resource' - Skip:(! $IsWindows ){
46
+ It ' Set works on Binary "File" resource' - Skip:(! $IsWindows ) {
47
47
48
- $testFile = " $testdrive \test.txt"
49
- $null = ' {"DestinationPath":"' + $testFile.replace (' \' , ' \\' ) + ' ", type: File, contents: HelloWorld, Ensure: present}' | dsc resource set - r ' PSDesiredStateConfiguration/File' -f -
50
- $LASTEXITCODE | Should - Be 0
51
- Get-Content - Raw - Path $testFile | Should - Be " HelloWorld"
52
- }
48
+ $testFile = " $testdrive \test.txt"
49
+ $null = ' {"DestinationPath":"' + $testFile.replace (' \' , ' \\' ) + ' ", type: File, contents: HelloWorld, Ensure: present}' | dsc resource set - r ' PSDesiredStateConfiguration/File' -f -
50
+ $LASTEXITCODE | Should - Be 0
51
+ Get-Content - Raw - Path $testFile | Should - Be " HelloWorld"
52
+ }
53
53
54
- It ' Get works on traditional "Script" resource' - Skip:(! $IsWindows ){
54
+ It ' Get works on traditional "Script" resource' - Skip:(! $IsWindows ) {
55
55
56
- $testFile = " $testdrive \test.txt"
57
- ' test' | Set-Content - Path $testFile - Force
58
- $r = ' {"GetScript": "@{result = $(Get-Content ' + $testFile.replace (' \' , ' \\' ) + ' )}", "SetScript": "throw", "TestScript": "throw"}' | dsc resource get - r ' PSDesiredStateConfiguration/Script' -f -
59
- $LASTEXITCODE | Should - Be 0
60
- $res = $r | ConvertFrom-Json
61
- $res.actualState.result | Should - Be ' test'
62
- }
56
+ $testFile = " $testdrive \test.txt"
57
+ ' test' | Set-Content - Path $testFile - Force
58
+ $r = ' {"GetScript": "@{result = $(Get-Content ' + $testFile.replace (' \' , ' \\' ) + ' )}", "SetScript": "throw", "TestScript": "throw"}' | dsc resource get - r ' PSDesiredStateConfiguration/Script' -f -
59
+ $LASTEXITCODE | Should - Be 0
60
+ $res = $r | ConvertFrom-Json
61
+ $res.actualState.result | Should - Be ' test'
62
+ }
63
63
64
- It ' Get works on config with File resource for WinPS' - Skip:(! $IsWindows ){
64
+ It ' Get works on config with File resource for WinPS' - Skip:(! $IsWindows ) {
65
65
66
- $testFile = " $testdrive \test.txt"
67
- ' test' | Set-Content - Path $testFile - Force
68
- $r = (Get-Content - Raw $winpsConfigPath ).Replace(' c:\test.txt' , " $testFile " ) | dsc config get -f -
69
- $LASTEXITCODE | Should - Be 0
70
- $res = $r | ConvertFrom-Json
71
- $res.results [0 ].result.actualState.result[0 ].properties.DestinationPath | Should - Be " $testFile "
72
- }
66
+ $testFile = " $testdrive \test.txt"
67
+ ' test' | Set-Content - Path $testFile - Force
68
+ $r = (Get-Content - Raw $winpsConfigPath ).Replace(' c:\test.txt' , " $testFile " ) | dsc config get -f -
69
+ $LASTEXITCODE | Should - Be 0
70
+ $res = $r | ConvertFrom-Json
71
+ $res.results [0 ].result.actualState.result[0 ].properties.DestinationPath | Should - Be " $testFile "
72
+ }
73
73
74
- It ' Verify that there are no cache rebuilds for several sequential executions' - Skip:(! $IsWindows ) {
75
- # remove cache file
76
- $cacheFilePath = Join-Path $env: LocalAppData " dsc\WindowsPSAdapterCache.json"
77
- Remove-Item - Force - Path $cacheFilePath - ErrorAction Ignore
74
+ It ' Verify that there are no cache rebuilds for several sequential executions' - Skip:(! $IsWindows ) {
75
+ # remove cache file
76
+ $cacheFilePath = Join-Path $env: LocalAppData " dsc\WindowsPSAdapterCache.json"
77
+ Remove-Item - Force - Path $cacheFilePath - ErrorAction Ignore
78
78
79
- # first execution should build the cache
80
- dsc - l trace resource list - a Microsoft.Windows/ WindowsPowerShell 2> $TestDrive / tracing.txt
81
- " $TestDrive /tracing.txt" | Should - FileContentMatchExactly ' Constructing Get-DscResource cache'
79
+ # first execution should build the cache
80
+ dsc - l trace resource list - a Microsoft.Windows/ WindowsPowerShell 2> $TestDrive / tracing.txt
81
+ " $TestDrive /tracing.txt" | Should - FileContentMatchExactly ' Constructing Get-DscResource cache'
82
82
83
- # next executions following shortly after should Not rebuild the cache
84
- 1 .. 3 | ForEach-Object {
85
- dsc - l trace resource list - a Microsoft.Windows/ WindowsPowerShell 2> $TestDrive / tracing.txt
86
- " $TestDrive /tracing.txt" | Should -Not - FileContentMatchExactly ' Constructing Get-DscResource cache'
87
- }
83
+ # next executions following shortly after should Not rebuild the cache
84
+ 1 .. 3 | ForEach-Object {
85
+ dsc - l trace resource list - a Microsoft.Windows/ WindowsPowerShell 2> $TestDrive / tracing.txt
86
+ " $TestDrive /tracing.txt" | Should -Not - FileContentMatchExactly ' Constructing Get-DscResource cache'
88
87
}
88
+ }
89
89
90
- It ' Verify if assertion is used that no module is cleared in the cache' - Skip:(! $IsWindows ) {
91
- # create a test file in the test drive
92
- $testFile = " $testdrive \test.txt"
93
- New-Item - Path $testFile - ItemType File - Force | Out-Null
90
+ It ' Verify if assertion is used that no module is cleared in the cache' - Skip:(! $IsWindows ) {
91
+ # create a test file in the test drive
92
+ $testFile = " $testdrive \test.txt"
93
+ New-Item - Path $testFile - ItemType File - Force | Out-Null
94
94
95
- # remove cache file
96
- $cacheFilePath = Join-Path $env: LocalAppData " dsc\WindowsPSAdapterCache.json"
97
- Remove-Item - Force - Path $cacheFilePath - ErrorAction Ignore
95
+ # remove cache file
96
+ $cacheFilePath = Join-Path $env: LocalAppData " dsc\WindowsPSAdapterCache.json"
97
+ Remove-Item - Force - Path $cacheFilePath - ErrorAction Ignore
98
98
99
- # build the cache
100
- dsc resource list -- adapter Microsoft.Windows/ WindowsPowerShell | Out-Null
99
+ # build the cache
100
+ dsc resource list -- adapter Microsoft.Windows/ WindowsPowerShell | Out-Null
101
101
102
- # Create a test module in the test drive
103
- $testModuleDir = " $testdrive \TestModule\1.0.0"
104
- New-Item - Path $testModuleDir - ItemType Directory - Force | Out-Null
102
+ # Create a test module in the test drive
103
+ $testModuleDir = " $testdrive \TestModule\1.0.0"
104
+ New-Item - Path $testModuleDir - ItemType Directory - Force | Out-Null
105
105
106
- $manifestContent = @"
106
+ $manifestContent = @"
107
107
@{
108
108
RootModule = 'TestModule.psm1'
109
109
ModuleVersion = '1.0.0'
@@ -120,17 +120,17 @@ Describe 'WindowsPowerShell adapter resource tests - requires elevated permissio
120
120
AliasesToExport = @()
121
121
}
122
122
"@
123
- Set-Content - Path " $testModuleDir \TestModule.psd1" - Value $manifestContent
123
+ Set-Content - Path " $testModuleDir \TestModule.psd1" - Value $manifestContent
124
124
125
- $scriptContent = @"
125
+ $scriptContent = @"
126
126
Write-Host 'The DSC world!'
127
127
"@
128
- Set-Content - Path " $testModuleDir \TestModule.psm1" - Value $scriptContent
128
+ Set-Content - Path " $testModuleDir \TestModule.psm1" - Value $scriptContent
129
129
130
- # Add the test module directory to PSModulePath
131
- $env: PSModulePath += [System.IO.Path ]::PathSeparator + $testdrive
130
+ # Add the test module directory to PSModulePath
131
+ $env: PSModulePath += [System.IO.Path ]::PathSeparator + $testdrive
132
132
133
- $yaml = @"
133
+ $yaml = @"
134
134
`$ schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
135
135
resources:
136
136
- name: File
@@ -164,25 +164,25 @@ resources:
164
164
- "[resourceId('Microsoft.Windows/WindowsPowerShell', 'File')]"
165
165
- "[resourceId('Microsoft.DSC/Assertion', 'File present')]"
166
166
"@
167
- # output to file for Windows PowerShell 5.1
168
- $filePath = " $testdrive \test.assertion.dsc.resource.yaml"
169
- $yaml | Set-Content - Path $filePath - Force
170
- dsc config test -f $filePath 2> " $TestDrive /error.txt"
171
- $LASTEXITCODE | Should - Be 2
172
-
173
- $cache = Get-Content - Path $cacheFilePath - Raw | ConvertFrom-Json
174
- $cache.ResourceCache.Type | Should - Contain ' PSTestModule/TestPSRepository'
175
- $cache.ResourceCache.Type | Should - Contain ' PSDesiredStateConfiguration/File'
176
- }
167
+ # output to file for Windows PowerShell 5.1
168
+ $filePath = " $testdrive \test.assertion.dsc.resource.yaml"
169
+ $yaml | Set-Content - Path $filePath - Force
170
+ dsc config test -f $filePath 2> " $TestDrive /error.txt"
171
+ $LASTEXITCODE | Should - Be 2
177
172
178
- It ' _inDesiredState is returned correction: <Context>' - Skip:(! $IsWindows ) - TestCases @ (
179
- @ { Context = ' Both running' ; FirstState = ' Running' ; SecondState = ' Running' }
180
- @ { Context = ' Both stopped' ; FirstState = ' Stopped' ; SecondState = ' Stopped' }
181
- @ { Context = ' First Stopped' ; FirstState = ' Stopped' ; SecondState = ' Running' }
182
- @ { Context = ' First Running' ; FirstState = ' Running' ; SecondState = ' Stopped' }
183
- ) {
184
- param ($Context , $FirstState , $SecondState )
185
- $yaml = @"
173
+ $cache = Get-Content - Path $cacheFilePath - Raw | ConvertFrom-Json
174
+ $cache.ResourceCache.Type | Should - Contain ' PSTestModule/TestPSRepository'
175
+ $cache.ResourceCache.Type | Should - Contain ' PSDesiredStateConfiguration/File'
176
+ }
177
+
178
+ It ' _inDesiredState is returned correction: <Context>' - Skip:(! $IsWindows ) - TestCases @ (
179
+ @ { Context = ' Both running' ; FirstState = ' Running' ; SecondState = ' Running' }
180
+ @ { Context = ' Both stopped' ; FirstState = ' Stopped' ; SecondState = ' Stopped' }
181
+ @ { Context = ' First Stopped' ; FirstState = ' Stopped' ; SecondState = ' Running' }
182
+ @ { Context = ' First Running' ; FirstState = ' Running' ; SecondState = ' Stopped' }
183
+ ) {
184
+ param ($Context , $FirstState , $SecondState )
185
+ $yaml = @"
186
186
`$ schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
187
187
resources:
188
188
- name: Use Windows PowerShell resources
@@ -201,18 +201,57 @@ resources:
201
201
State: $SecondState
202
202
"@
203
203
204
- $inDesiredState = if ($FirstState -eq $SecondState ) {
205
- $FirstState -eq (Get-Service Spooler).Status
206
- } else {
207
- $false
208
- }
204
+ $inDesiredState = if ($FirstState -eq $SecondState ) {
205
+ $FirstState -eq (Get-Service Spooler).Status
206
+ }
207
+ else {
208
+ $false
209
+ }
210
+
211
+ $out = dsc config test - i $yaml | ConvertFrom-Json
212
+ $LASTEXITCODE | Should - Be 0
213
+ $out.results [0 ].result.inDesiredState | Should - Be $inDesiredState
214
+ }
209
215
210
- $out = dsc config test - i $yaml | ConvertFrom-Json
211
- $LASTEXITCODE | Should - Be 0
212
- $out.results [0 ].result.inDesiredState | Should - Be $inDesiredState
216
+ It ' Config works with credential object' {
217
+ BeforeAll {
218
+ $script :winPSModule = Resolve-Path - Path (Join-Path $PSScriptRoot ' ..' ' powershell-adapter' ' psDscAdapter' ' win_psDscAdapter.psm1' ) | Select-Object - ExpandProperty Path
219
+ Import-Module $winPSModule - Force - ErrorAction Stop
220
+
221
+ # Mock the command to work on GitHub runners because Microsoft.PowerShell.Security is not available
222
+ Mock - CommandName ConvertTo-SecureString - MockWith { [System.Security.SecureString ]::new() }
223
+ }
224
+
225
+ AfterAll {
226
+ Remove-Module $script :winPSModule - Force - ErrorAction Ignore
213
227
}
214
228
215
- It ' Config does not work when credential properties are missing required fields' - Skip:(! $IsWindows ) {
229
+ $jsonInput = @ {
230
+ resources = @ {
231
+ name = ' Service info'
232
+ type = ' PSDesiredStateConfiguration/Service'
233
+ properties = @ {
234
+ Name = ' Spooler'
235
+ Credential = @ {
236
+ UserName = ' User'
237
+ Password = ' Password'
238
+ }
239
+ }
240
+ }
241
+ } | ConvertTo-Json - Depth 10
242
+
243
+ # Instead of calling dsc.exe we call the cmdlet directly to be able to test the output and mocks
244
+ $resourceObject = Get-DscResourceObject - jsonInput $jsonInput
245
+ $cacheEntry = Invoke-DscCacheRefresh - Module PSDesiredStateConfiguration
246
+
247
+ $out = Invoke-DscOperation - Operation Test - DesiredState $resourceObject - dscResourceCache $cacheEntry
248
+ $LASTEXITCODE | Should - Be 0
249
+ $out.properties.InDesiredState.InDesiredState | Should - Be $false
250
+
251
+ Should - Invoke - CommandName ConvertTo-SecureString - Exactly - Times 1 - Scope It
252
+ }
253
+
254
+ It ' Config does not work when credential properties are missing required fields' - Skip:(! $IsWindows ) {
216
255
$yaml = @"
217
256
`$ schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
218
257
resources:
@@ -224,8 +263,8 @@ resources:
224
263
UserName: 'User'
225
264
OtherProperty: 'Password'
226
265
"@
227
- dsc - l trace config get - i $yaml
228
- $out = dsc - l trace config get - i $yaml 2>&1 | Out-String
266
+ # Compared to PowerShell we use test here as it filters out the properties
267
+ $out = dsc config test - i $yaml 2>&1 | Out-String
229
268
$LASTEXITCODE | Should - Be 2
230
269
$out | Should -Not - BeNullOrEmpty
231
270
$out | Should - BeLike " *ERROR*Credential object 'Credential' requires both 'username' and 'password' properties*"
0 commit comments