Skip to content

Commit 23b4d92

Browse files
committed
Add mock example on Windows Powershell
1 parent fbb3a94 commit 23b4d92

File tree

1 file changed

+152
-113
lines changed

1 file changed

+152
-113
lines changed

powershell-adapter/Tests/win_powershellgroup.tests.ps1

Lines changed: 152 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -3,107 +3,107 @@
33

44
Describe '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 = @"
126126
Write-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
135135
resources:
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
187187
resources:
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

Comments
 (0)