From 6f39f536a33376c2017451f2a457a55bbf7836f8 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Tue, 20 May 2025 21:07:00 -0700 Subject: [PATCH 1/4] Fix `DSC_RESOURCE_PATH` env var to also limit exe search --- dsc/tests/dsc_discovery.tests.ps1 | 28 ++++++++++++++++++++++ dsc_lib/src/discovery/command_discovery.rs | 12 ++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/dsc/tests/dsc_discovery.tests.ps1 b/dsc/tests/dsc_discovery.tests.ps1 index d6802420..2f75f4d5 100644 --- a/dsc/tests/dsc_discovery.tests.ps1 +++ b/dsc/tests/dsc_discovery.tests.ps1 @@ -220,4 +220,32 @@ Describe 'tests for resource discovery' { $env:DSC_RESOURCE_PATH = $oldPath } } + + It 'DSC_RESOURCE_PATH should be used for executable lookup' { + $dscTest = Get-Command dscecho -ErrorAction Stop + $target = if ($IsWindows) { + 'echoIt.exe' + } else { + 'echoIt' + } + Copy-Item -Path "$($dscTest.Source)" -Destination "$testdrive\$target" + $manifest = Get-Content -Raw -Path "$(Split-Path -Path $dscTest.Source -Parent)\echo.dsc.resource.json" | ConvertFrom-Json + $manifest.type = 'Test/MyEcho' + $manifest.get.executable = $target + $manifest.set = $null + $manifest.test = $null + $manifest.schema.command.executable = $target + Set-Content -Path "$testdrive/test.dsc.resource.json" -Value ($manifest | ConvertTo-Json -Depth 10) + + $oldPath = $env:DSC_RESOURCE_PATH + try { + $env:DSC_RESOURCE_PATH = $testdrive + $out = dsc resource get -r 'Test/MyEcho' -i '{"output":"Custom"}' 2> "$testdrive/error.txt" | ConvertFrom-Json + $LASTEXITCODE | Should -Be 0 + $out.actualState.output | Should -BeExactly 'Custom' + } + finally { + $env:DSC_RESOURCE_PATH = $oldPath + } + } } diff --git a/dsc_lib/src/discovery/command_discovery.rs b/dsc_lib/src/discovery/command_discovery.rs index ec604ee3..5c8e1706 100644 --- a/dsc_lib/src/discovery/command_discovery.rs +++ b/dsc_lib/src/discovery/command_discovery.rs @@ -149,8 +149,16 @@ impl CommandDiscovery { let mut uniques: HashSet = HashSet::new(); paths.retain(|e|uniques.insert((*e).clone())); - // if exe home is not already in PATH env var then add it to env var and list of searched paths - if !using_custom_path { + if using_custom_path { + // when using custom path, intent is to isolate the search of manifests and executables to the custom path + // so we replace the PATH with the custom path + if let Ok(new_path) = env::join_paths(paths.clone()) { + env::set_var("PATH", new_path); + } else { + return Err(DscError::Operation(t!("discovery.commandDiscovery.failedSetEnvPath").to_string())); + } + } else { + // if exe home is not already in PATH env var then add it to env var and list of searched paths if let Some(exe_home) = get_exe_path()?.parent() { let exe_home_pb = exe_home.to_path_buf(); if paths.contains(&exe_home_pb) { From 9aa9eb675505c57ac6a67a44a46997819bea1d1d Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Tue, 20 May 2025 21:29:40 -0700 Subject: [PATCH 2/4] enhance test to validate PATH isn't searched --- dsc/tests/dsc_discovery.tests.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dsc/tests/dsc_discovery.tests.ps1 b/dsc/tests/dsc_discovery.tests.ps1 index 2f75f4d5..6d377a3b 100644 --- a/dsc/tests/dsc_discovery.tests.ps1 +++ b/dsc/tests/dsc_discovery.tests.ps1 @@ -243,6 +243,9 @@ Describe 'tests for resource discovery' { $out = dsc resource get -r 'Test/MyEcho' -i '{"output":"Custom"}' 2> "$testdrive/error.txt" | ConvertFrom-Json $LASTEXITCODE | Should -Be 0 $out.actualState.output | Should -BeExactly 'Custom' + dsc resource get -r 'Microsoft.DSC.Debug/Echo' -i '{"output":"Custom"}' 2> "$testdrive/error.txt" | ConvertFrom-Json + $LASTEXITCODE | Should -Be 7 + Get-Content -Raw -Path "$testdrive/error.txt" | Should -Match "ERROR.*?Resource not found" } finally { $env:DSC_RESOURCE_PATH = $oldPath From ca2473d569aaa9837bcd1f00125e4b921c63f909 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Tue, 3 Jun 2025 14:06:42 -0700 Subject: [PATCH 3/4] Fix tests --- dsc/tests/dsc_extension_discover.tests.ps1 | 5 ++--- dsc/tests/dsc_resource_input.tests.ps1 | 2 +- dsc/tests/dsc_set.tests.ps1 | 4 ++-- dsc_lib/locales/en-us.toml | 1 + dsc_lib/src/discovery/command_discovery.rs | 2 +- runcommandonset/tests/runcommandonset.get.tests.ps1 | 10 +--------- runcommandonset/tests/runcommandonset.set.tests.ps1 | 9 --------- 7 files changed, 8 insertions(+), 25 deletions(-) diff --git a/dsc/tests/dsc_extension_discover.tests.ps1 b/dsc/tests/dsc_extension_discover.tests.ps1 index ff5f9204..9dd0669f 100644 --- a/dsc/tests/dsc_extension_discover.tests.ps1 +++ b/dsc/tests/dsc_extension_discover.tests.ps1 @@ -4,9 +4,8 @@ Describe 'Discover extension tests' { BeforeAll { $oldPath = $env:PATH - $separator = [System.IO.Path]::PathSeparator $toolPath = Resolve-Path -Path "$PSScriptRoot/../../extensions/test/discover" - $env:PATH = "$toolPath$separator$oldPath" + $env:PATH = $toolPath + [System.IO.Path]::PathSeparator + $oldPath } AfterAll { @@ -75,7 +74,7 @@ Describe 'Discover extension tests' { Set-Content -Path "$TestDrive/test.dsc.extension.json" -Value $extension_json Copy-Item -Path "$toolPath/discover.ps1" -Destination $TestDrive | Out-Null Copy-Item -Path "$toolPath/resources" -Destination $TestDrive -Recurse | Out-Null - $env:DSC_RESOURCE_PATH = $TestDrive + $env:DSC_RESOURCE_PATH = "$TestDrive$separator$oldPath" try { $out = dsc extension list | ConvertFrom-Json $out.Count | Should -Be 1 diff --git a/dsc/tests/dsc_resource_input.tests.ps1 b/dsc/tests/dsc_resource_input.tests.ps1 index 75da7094..74f33bf7 100644 --- a/dsc/tests/dsc_resource_input.tests.ps1 +++ b/dsc/tests/dsc_resource_input.tests.ps1 @@ -85,7 +85,7 @@ Describe 'tests for resource input' { } '@ $oldPath = $env:DSC_RESOURCE_PATH - $env:DSC_RESOURCE_PATH = $TestDrive + $env:DSC_RESOURCE_PATH = $TestDrive + [System.IO.Path]::PathSeparator + $env:PATH Set-Content $TestDrive/EnvVarInput.dsc.resource.json -Value $manifest } diff --git a/dsc/tests/dsc_set.tests.ps1 b/dsc/tests/dsc_set.tests.ps1 index 8a58cbbb..d6fa25a7 100644 --- a/dsc/tests/dsc_set.tests.ps1 +++ b/dsc/tests/dsc_set.tests.ps1 @@ -147,7 +147,7 @@ changedProperties: $oldPath = $env:DSC_RESOURCE_PATH try { - $env:DSC_RESOURCE_PATH = $TestDrive + $env:DSC_RESOURCE_PATH = $TestDrive + [System.IO.Path]::PathSeparator + $env:PATH $out = '{ "test": true }' | dsc resource set -r Test/SetNoTest -f - --output-format $format | Out-String $LASTEXITCODE | Should -Be 0 $out.Trim() | Should -BeExactly $expected @@ -160,7 +160,7 @@ changedProperties: It 'set can be used on a resource that does not implement test' { $oldPath = $env:DSC_RESOURCE_PATH try { - $env:DSC_RESOURCE_PATH = $TestDrive + $env:DSC_RESOURCE_PATH = $TestDrive + [System.IO.Path]::PathSeparator + $env:PATH $out = '{ "test": true }' | dsc resource set -r Test/SetNoTest -f - | ConvertFrom-Json $LASTEXITCODE | Should -Be 0 $out.BeforeState.test | Should -Be $true diff --git a/dsc_lib/locales/en-us.toml b/dsc_lib/locales/en-us.toml index 528faf55..2b89e7b8 100644 --- a/dsc_lib/locales/en-us.toml +++ b/dsc_lib/locales/en-us.toml @@ -72,6 +72,7 @@ couldNotReadSetting = "Could not read 'resourcePath' setting" appendingEnvPath = "Appending PATH to resourcePath" originalPath = "Original PATH: %{path}" failedGetEnvPath = "Failed to get PATH environment variable" +failedJoinEnvPath = "Failed to join PATH environment variable" exeHomeAlreadyInPath = "Exe home is already in path: %{path}" addExeHomeToPath = "Adding exe home to path: %{path}" usingResourcePath = "Using Resource Path: %{path}" diff --git a/dsc_lib/src/discovery/command_discovery.rs b/dsc_lib/src/discovery/command_discovery.rs index 5c8e1706..61bacc2b 100644 --- a/dsc_lib/src/discovery/command_discovery.rs +++ b/dsc_lib/src/discovery/command_discovery.rs @@ -155,7 +155,7 @@ impl CommandDiscovery { if let Ok(new_path) = env::join_paths(paths.clone()) { env::set_var("PATH", new_path); } else { - return Err(DscError::Operation(t!("discovery.commandDiscovery.failedSetEnvPath").to_string())); + return Err(DscError::Operation(t!("discovery.commandDiscovery.failedJoinEnvPath").to_string())); } } else { // if exe home is not already in PATH env var then add it to env var and list of searched paths diff --git a/runcommandonset/tests/runcommandonset.get.tests.ps1 b/runcommandonset/tests/runcommandonset.get.tests.ps1 index 18b50ac4..aec3ddab 100644 --- a/runcommandonset/tests/runcommandonset.get.tests.ps1 +++ b/runcommandonset/tests/runcommandonset.get.tests.ps1 @@ -2,15 +2,6 @@ # Licensed under the MIT License. Describe 'tests for runcommandonset get' { - BeforeAll { - $oldPath = $env:DSC_RESOURCE_PATH - $env:DSC_RESOURCE_PATH = Join-Path $PSScriptRoot ".." - } - - AfterAll { - $env:DSC_RESOURCE_PATH = $oldPath - } - It 'Input passed for executable, arguments, and exit code' { $json = @" { @@ -21,6 +12,7 @@ Describe 'tests for runcommandonset get' { "@ $result = $json | dsc resource get -r Microsoft.DSC.Transitional/RunCommandOnSet -f - | ConvertFrom-Json + $LASTEXITCODE | Should -Be 0 $result.actualState.arguments | Should -BeExactly @('bar', 'baz') $result.actualState.executable | Should -BeExactly 'foo' $result.actualState.exitCode | Should -BeExactly 5 diff --git a/runcommandonset/tests/runcommandonset.set.tests.ps1 b/runcommandonset/tests/runcommandonset.set.tests.ps1 index 6f38ea0e..3ca57e9f 100644 --- a/runcommandonset/tests/runcommandonset.set.tests.ps1 +++ b/runcommandonset/tests/runcommandonset.set.tests.ps1 @@ -2,21 +2,12 @@ # Licensed under the MIT License. Describe 'tests for runcommandonset set' { - BeforeAll { - $oldPath = $env:DSC_RESOURCE_PATH - $env:DSC_RESOURCE_PATH = Join-Path $PSScriptRoot ".." - } - AfterEach { if (Test-Path $TestDrive/output.txt) { Remove-Item -Path $TestDrive/output.txt } } - AfterAll { - $env:DSC_RESOURCE_PATH = $oldPath - } - It 'Input for executable and arguments can be sent to the resource' { $input_json = @" { From 80b4ad5109c09d8eb17d29bd0973054c8615bab2 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Tue, 3 Jun 2025 14:25:36 -0700 Subject: [PATCH 4/4] Fix path in test --- dsc/tests/dsc_extension_discover.tests.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dsc/tests/dsc_extension_discover.tests.ps1 b/dsc/tests/dsc_extension_discover.tests.ps1 index 9dd0669f..d865c959 100644 --- a/dsc/tests/dsc_extension_discover.tests.ps1 +++ b/dsc/tests/dsc_extension_discover.tests.ps1 @@ -5,7 +5,7 @@ Describe 'Discover extension tests' { BeforeAll { $oldPath = $env:PATH $toolPath = Resolve-Path -Path "$PSScriptRoot/../../extensions/test/discover" - $env:PATH = $toolPath + [System.IO.Path]::PathSeparator + $oldPath + $env:PATH = "$toolPath" + [System.IO.Path]::PathSeparator + $oldPath } AfterAll { @@ -74,10 +74,10 @@ Describe 'Discover extension tests' { Set-Content -Path "$TestDrive/test.dsc.extension.json" -Value $extension_json Copy-Item -Path "$toolPath/discover.ps1" -Destination $TestDrive | Out-Null Copy-Item -Path "$toolPath/resources" -Destination $TestDrive -Recurse | Out-Null - $env:DSC_RESOURCE_PATH = "$TestDrive$separator$oldPath" + $env:DSC_RESOURCE_PATH = "$TestDrive" + [System.IO.Path]::PathSeparator + (Split-Path (Get-Command pwsh).Source -Parent) try { $out = dsc extension list | ConvertFrom-Json - $out.Count | Should -Be 1 + $out.Count | Should -Be 1 -Because ($out | Out-String) $out.type | Should -Be 'Test/DiscoverRelative' $out = dsc resource list 2> $TestDrive/error.log write-verbose -verbose (Get-Content -Path "$TestDrive/error.log" -Raw)