Skip to content

Commit 9fc9a80

Browse files
authored
Merge pull request #748 from Gijsreyn/fix-module-add-run-ps
Fix resourceCache to return proper modules when PS modules are installed during run
2 parents 4407d22 + 99bfd3e commit 9fc9a80

File tree

2 files changed

+104
-4
lines changed

2 files changed

+104
-4
lines changed

powershell-adapter/Tests/win_powershellgroup.tests.ps1

+90-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Describe 'WindowsPowerShell adapter resource tests - requires elevated permissio
3030
$r = dsc resource list --adapter Microsoft.Windows/WindowsPowerShell
3131
$LASTEXITCODE | Should -Be 0
3232
$resources = $r | ConvertFrom-Json
33-
($resources | ? {$_.Type -eq 'PSDesiredStateConfiguration/File'}).Count | Should -Be 1
33+
($resources | Where-Object {$_.Type -eq 'PSDesiredStateConfiguration/File'}).Count | Should -Be 1
3434
}
3535

3636
It 'Get works on Binary "File" resource' -Skip:(!$IsWindows){
@@ -72,7 +72,6 @@ Describe 'WindowsPowerShell adapter resource tests - requires elevated permissio
7272
}
7373

7474
It 'Verify that there are no cache rebuilds for several sequential executions' -Skip:(!$IsWindows) {
75-
7675
# remove cache file
7776
$cacheFilePath = Join-Path $env:LocalAppData "dsc\WindowsPSAdapterCache.json"
7877
Remove-Item -Force -Path $cacheFilePath -ErrorAction Ignore
@@ -82,12 +81,100 @@ Describe 'WindowsPowerShell adapter resource tests - requires elevated permissio
8281
"$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'Constructing Get-DscResource cache'
8382

8483
# next executions following shortly after should Not rebuild the cache
85-
1..3 | %{
84+
1..3 | ForEach-Object {
8685
dsc -l trace resource list -a Microsoft.Windows/WindowsPowerShell 2> $TestDrive/tracing.txt
8786
"$TestDrive/tracing.txt" | Should -Not -FileContentMatchExactly 'Constructing Get-DscResource cache'
8887
}
8988
}
9089

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+
95+
# remove cache file
96+
$cacheFilePath = Join-Path $env:LocalAppData "dsc\WindowsPSAdapterCache.json"
97+
Remove-Item -Force -Path $cacheFilePath -ErrorAction Ignore
98+
99+
# build the cache
100+
dsc resource list --adapter Microsoft.Windows/WindowsPowerShell | Out-Null
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
105+
106+
$manifestContent = @"
107+
@{
108+
RootModule = 'TestModule.psm1'
109+
ModuleVersion = '1.0.0'
110+
GUID = $([guid]::NewGuid().Guid)
111+
Author = 'Microsoft Corporation'
112+
CompanyName = 'Microsoft Corporation'
113+
Copyright = '(c) Microsoft Corporation. All rights reserved.'
114+
Description = 'Test module for DSC tests'
115+
PowerShellVersion = '5.1'
116+
DscResourcesToExport = @()
117+
FunctionsToExport = @()
118+
CmdletsToExport = @()
119+
VariablesToExport = @()
120+
AliasesToExport = @()
121+
}
122+
"@
123+
Set-Content -Path "$testModuleDir\TestModule.psd1" -Value $manifestContent
124+
125+
$scriptContent = @"
126+
Write-Host 'The DSC world!'
127+
"@
128+
Set-Content -Path "$testModuleDir\TestModule.psm1" -Value $scriptContent
129+
130+
# Add the test module directory to PSModulePath
131+
$env:PSModulePath += [System.IO.Path]::PathSeparator + $testdrive
132+
133+
$yaml = @"
134+
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
135+
resources:
136+
- name: File
137+
type: Microsoft.Windows/WindowsPowerShell
138+
properties:
139+
resources:
140+
- name: File
141+
type: PSDesiredStateConfiguration/File
142+
properties:
143+
DestinationPath: $testfile
144+
- name: File present
145+
type: Microsoft.DSC/Assertion
146+
properties:
147+
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
148+
resources:
149+
- name: Use powershell adapter
150+
type: Microsoft.Windows/WindowsPowerShell
151+
properties:
152+
resources:
153+
- name: File present
154+
type: PSDesiredStateConfiguration/File
155+
properties:
156+
DestinationPath: $testFile
157+
dependsOn:
158+
- "[resourceId('Microsoft.Windows/WindowsPowerShell', 'File')]"
159+
- name: TestPSRepository
160+
type: PSTestModule/TestPSRepository
161+
properties:
162+
Name: NuGet
163+
dependsOn:
164+
- "[resourceId('Microsoft.Windows/WindowsPowerShell', 'File')]"
165+
- "[resourceId('Microsoft.DSC/Assertion', 'File present')]"
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+
}
177+
91178
It '_inDesiredState is returned correction: <Context>' -Skip:(!$IsWindows) -TestCases @(
92179
@{ Context = 'Both running'; FirstState = 'Running'; SecondState = 'Running' }
93180
@{ Context = 'Both stopped'; FirstState = 'Stopped'; SecondState = 'Stopped' }

powershell-adapter/psDscAdapter/win_psDscAdapter.psm1

+14-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ function Invoke-DscCacheRefresh {
127127
$diff = $hs_cache
128128

129129
"PSModulePath diff '$diff'" | Write-DscTrace
130-
131130
if ($diff.Count -gt 0) {
132131
$refreshCache = $true
133132
}
@@ -154,10 +153,17 @@ function Invoke-DscCacheRefresh {
154153
}
155154
$DscResources = [System.Collections.Generic.List[Object]]::new()
156155
$Modules = [System.Collections.Generic.List[Object]]::new()
156+
$filteredResources = @()
157157
foreach ($m in $module) {
158158
$DscResources += Get-DscResource -Module $m
159159
$Modules += Get-Module -Name $m -ListAvailable
160+
161+
# Grab all DSC resources to filter out of the cache
162+
$filteredResources += $dscResources | Where-Object -Property ModuleName -NE $null | ForEach-Object { [System.String]::Concat($_.ModuleName, '/', $_.Name) }
160163
}
164+
165+
# Exclude the one module that was passed in as a parameter
166+
$existingDscResourceCacheEntries = $cache.ResourceCache | Where-Object -Property Type -NotIn $filteredResources
161167
}
162168
elseif ('PSDesiredStateConfiguration' -eq $module -and $PSVersionTable.PSVersion.Major -le 5 ) {
163169
# the resources in Windows should only load in Windows PowerShell
@@ -248,6 +254,13 @@ function Invoke-DscCacheRefresh {
248254
$cache.PSModulePaths = $m.FullName
249255
$cache.CacheSchemaVersion = $script:CurrentCacheSchemaVersion
250256

257+
if ($existingDscResourceCacheEntries) {
258+
$cache.ResourceCache += $existingDscResourceCacheEntries
259+
260+
# Make sure all resource cache entries are returned
261+
$dscResourceCacheEntries = $cache.ResourceCache
262+
}
263+
251264
# save cache for future use
252265
# TODO: replace this with a high-performance serializer
253266
"Saving Get-DscResource cache to '$cacheFilePath'" | Write-DscTrace

0 commit comments

Comments
 (0)