33
44Describe ' WindowsPowerShell adapter resource tests - requires elevated permissions' {
55
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
179 }
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"
2016 }
17+ }
18+ AfterAll {
19+ $env: PSModulePath = $OldPSModulePath
20+ }
2121
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
2625 }
26+ }
2727
28- It ' Windows PowerShell adapter supports File resource' - Skip:(! $IsWindows ){
28+ It ' Windows PowerShell adapter supports File resource' - Skip:(! $IsWindows ) {
2929
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+ }
3535
36- It ' Get works on Binary "File" resource' - Skip:(! $IsWindows ){
36+ It ' Get works on Binary "File" resource' - Skip:(! $IsWindows ) {
3737
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+ }
4545
46- It ' Set works on Binary "File" resource' - Skip:(! $IsWindows ){
46+ It ' Set works on Binary "File" resource' - Skip:(! $IsWindows ) {
4747
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+ }
5353
54- It ' Get works on traditional "Script" resource' - Skip:(! $IsWindows ){
54+ It ' Get works on traditional "Script" resource' - Skip:(! $IsWindows ) {
5555
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+ }
6363
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 ) {
6565
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+ }
7373
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
7878
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'
8282
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'
8887 }
88+ }
8989
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
9494
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
9898
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
101101
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
105105
106- $manifestContent = @"
106+ $manifestContent = @"
107107 @{
108108 RootModule = 'TestModule.psm1'
109109 ModuleVersion = '1.0.0'
@@ -120,17 +120,17 @@ Describe 'WindowsPowerShell adapter resource tests - requires elevated permissio
120120 AliasesToExport = @()
121121 }
122122"@
123- Set-Content - Path " $testModuleDir \TestModule.psd1" - Value $manifestContent
123+ Set-Content - Path " $testModuleDir \TestModule.psd1" - Value $manifestContent
124124
125- $scriptContent = @"
125+ $scriptContent = @"
126126Write-Host 'The DSC world!'
127127"@
128- Set-Content - Path " $testModuleDir \TestModule.psm1" - Value $scriptContent
128+ Set-Content - Path " $testModuleDir \TestModule.psm1" - Value $scriptContent
129129
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
132132
133- $yaml = @"
133+ $yaml = @"
134134`$ schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
135135resources:
136136 - name: File
@@ -164,25 +164,25 @@ resources:
164164 - "[resourceId('Microsoft.Windows/WindowsPowerShell', 'File')]"
165165 - "[resourceId('Microsoft.DSC/Assertion', 'File present')]"
166166"@
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
177172
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 = @"
186186`$ schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
187187resources:
188188 - name: Use Windows PowerShell resources
@@ -201,18 +201,57 @@ resources:
201201 State: $SecondState
202202"@
203203
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+ }
209215
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
213227 }
214228
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 ) {
216255 $yaml = @"
217256 `$ schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
218257 resources:
@@ -224,8 +263,8 @@ resources:
224263 UserName: 'User'
225264 OtherProperty: 'Password'
226265"@
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
229268 $LASTEXITCODE | Should - Be 2
230269 $out | Should -Not - BeNullOrEmpty
231270 $out | Should - BeLike " *ERROR*Credential object 'Credential' requires both 'username' and 'password' properties*"
0 commit comments