From 921fa080d670836caea874a1ee432d698137f17c Mon Sep 17 00:00:00 2001 From: anamnavi Date: Wed, 20 Aug 2025 23:25:44 -0400 Subject: [PATCH 1/5] update ResponseUtil.ConvertToPSResourceResult() to take a bool parameter to eval if resource name contained wildcard when assessing if pkg version is unlisted --- src/code/ContainerRegistryResponseUtil.cs | 2 +- src/code/FindHelper.cs | 15 +++++++++++++-- src/code/LocalResponseUtil.cs | 2 +- src/code/NuGetServerResponseUtil.cs | 2 +- src/code/ResponseUtil.cs | 2 +- src/code/V2ResponseUtil.cs | 5 +++-- src/code/V3ResponseUtil.cs | 2 +- 7 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/code/ContainerRegistryResponseUtil.cs b/src/code/ContainerRegistryResponseUtil.cs index 1bb509d9e..295ae45a6 100644 --- a/src/code/ContainerRegistryResponseUtil.cs +++ b/src/code/ContainerRegistryResponseUtil.cs @@ -28,7 +28,7 @@ public ContainerRegistryResponseUtil(PSRepositoryInfo repository) : base(reposit #region Overriden Methods - public override IEnumerable ConvertToPSResourceResult(FindResults responseResults) + public override IEnumerable ConvertToPSResourceResult(FindResults responseResults, bool isResourceRequestedWithWildcard = false) { Hashtable[] responses = responseResults.HashtableResponse; foreach (Hashtable response in responses) diff --git a/src/code/FindHelper.cs b/src/code/FindHelper.cs index 2f34f7453..d8287c689 100644 --- a/src/code/FindHelper.cs +++ b/src/code/FindHelper.cs @@ -689,6 +689,7 @@ private IEnumerable SearchByNames(ServerApiCall currentServer, R ErrorRecord errRecord = null; List parentPkgs = new List(); string tagsAsString = String.Empty; + bool isV2Resource = currentResponseUtil is V2ResponseUtil; _cmdletPassedIn.WriteDebug("In FindHelper::SearchByNames()"); foreach (string pkgName in _pkgsLeftToFind.ToArray()) @@ -699,6 +700,12 @@ private IEnumerable SearchByNames(ServerApiCall currentServer, R { _cmdletPassedIn.WriteDebug("No version specified, package name is '*'"); // Example: Find-PSResource -Name "*" + + // Note: Just for resources from V2 servers, specifically PSGallery, if the resource is unlisted and was requested non-explicitly + // (i.e requested name has wildcard) the resource should not be returned and ResponseUtil.ConvertToPSResourceResult() call needs to be informed of this. + // In all other cases, return the resource regardless of whether it was requested explicitly or not. + bool isResourceRequestedWithWildcard = isV2Resource; + FindResults responses = currentServer.FindAll(_prerelease, _type, out errRecord); if (errRecord != null) { @@ -714,7 +721,7 @@ private IEnumerable SearchByNames(ServerApiCall currentServer, R continue; } - foreach (PSResourceResult currentResult in currentResponseUtil.ConvertToPSResourceResult(responseResults: responses)) + foreach (PSResourceResult currentResult in currentResponseUtil.ConvertToPSResourceResult(responseResults: responses, isResourceRequestedWithWildcard)) { if (currentResult.exception != null && !currentResult.exception.Message.Equals(string.Empty)) { @@ -745,6 +752,10 @@ private IEnumerable SearchByNames(ServerApiCall currentServer, R // Example: Find-PSResource -Name "Az*" -Tag "Storage" _cmdletPassedIn.WriteDebug("No version specified, package name contains a wildcard."); + // Note: Just for resources from V2 servers, specifically PSGallery, if the resource is unlisted and was requested non-explicitly + // (i.e requested name has wildcard) the resource should not be returned and ResponseUtil.ConvertToPSResourceResult() call needs to be informed of this. + // In all other cases, return the resource regardless of whether it was requested explicitly or not. + bool isResourceRequestedWithWildcard = isV2Resource; FindResults responses = null; if (_tag.Length == 0) { @@ -770,7 +781,7 @@ private IEnumerable SearchByNames(ServerApiCall currentServer, R continue; } - foreach (PSResourceResult currentResult in currentResponseUtil.ConvertToPSResourceResult(responses)) + foreach (PSResourceResult currentResult in currentResponseUtil.ConvertToPSResourceResult(responses, isResourceRequestedWithWildcard)) { if (currentResult.exception != null && !currentResult.exception.Message.Equals(string.Empty)) { diff --git a/src/code/LocalResponseUtil.cs b/src/code/LocalResponseUtil.cs index f82c6db81..103f4df2a 100644 --- a/src/code/LocalResponseUtil.cs +++ b/src/code/LocalResponseUtil.cs @@ -27,7 +27,7 @@ public LocalResponseUtil(PSRepositoryInfo repository) : base(repository) #endregion #region Overriden Methods - public override IEnumerable ConvertToPSResourceResult(FindResults responseResults) + public override IEnumerable ConvertToPSResourceResult(FindResults responseResults, bool isResourceRequestedWithWildcard = false) { foreach (Hashtable response in responseResults.HashtableResponse) { diff --git a/src/code/NuGetServerResponseUtil.cs b/src/code/NuGetServerResponseUtil.cs index 3a553e4ed..2223e4b19 100644 --- a/src/code/NuGetServerResponseUtil.cs +++ b/src/code/NuGetServerResponseUtil.cs @@ -26,7 +26,7 @@ public NuGetServerResponseUtil(PSRepositoryInfo repository) : base(repository) #endregion #region Overriden Methods - public override IEnumerable ConvertToPSResourceResult(FindResults responseResults) + public override IEnumerable ConvertToPSResourceResult(FindResults responseResults, bool isResourceRequestedWithWildcard = false) { // in FindHelper: // serverApi.FindName() -> return responses, and out errRecord diff --git a/src/code/ResponseUtil.cs b/src/code/ResponseUtil.cs index 40d6f9fc0..aac2cdbd1 100644 --- a/src/code/ResponseUtil.cs +++ b/src/code/ResponseUtil.cs @@ -25,7 +25,7 @@ public ResponseUtil(PSRepositoryInfo repository) #region Methods - public abstract IEnumerable ConvertToPSResourceResult(FindResults responseResults); + public abstract IEnumerable ConvertToPSResourceResult(FindResults responseResults, bool isResourceRequestedWithWildcard = false); #endregion diff --git a/src/code/V2ResponseUtil.cs b/src/code/V2ResponseUtil.cs index 4025f0c83..af2435ad1 100644 --- a/src/code/V2ResponseUtil.cs +++ b/src/code/V2ResponseUtil.cs @@ -28,7 +28,7 @@ public V2ResponseUtil(PSRepositoryInfo repository) : base(repository) #endregion #region Overriden Methods - public override IEnumerable ConvertToPSResourceResult(FindResults responseResults) + public override IEnumerable ConvertToPSResourceResult(FindResults responseResults, bool isResourceRequestedWithWildcard = false) { // in FindHelper: // serverApi.FindName() -> return responses, and out errRecord @@ -58,8 +58,9 @@ public override IEnumerable ConvertToPSResourceResult(FindResu yield return new PSResourceResult(returnedObject: null, exception: parseException, isTerminatingError: false); } + // For V2 resources, specifically PSGallery, return unlisted version resources only when not requested with wildcard name // Unlisted versions will have a published year as 1900 or earlier. - if (!psGetInfo.PublishedDate.HasValue || psGetInfo.PublishedDate.Value.Year > 1900) + if (!isResourceRequestedWithWildcard || !psGetInfo.PublishedDate.HasValue || psGetInfo.PublishedDate.Value.Year > 1900) { yield return new PSResourceResult(returnedObject: psGetInfo, exception: null, isTerminatingError: false); } diff --git a/src/code/V3ResponseUtil.cs b/src/code/V3ResponseUtil.cs index d819e146d..ec122cd8d 100644 --- a/src/code/V3ResponseUtil.cs +++ b/src/code/V3ResponseUtil.cs @@ -27,7 +27,7 @@ public V3ResponseUtil(PSRepositoryInfo repository) : base(repository) #region Overriden Methods - public override IEnumerable ConvertToPSResourceResult(FindResults responseResults) + public override IEnumerable ConvertToPSResourceResult(FindResults responseResults, bool isResourceRequestedWithWildcard = false) { // in FindHelper: // serverApi.FindName() -> return responses, and out errRecord From 1748fbd84edc5ad07f7ca44ad57afc58674b0974 Mon Sep 17 00:00:00 2001 From: anamnavi Date: Thu, 21 Aug 2025 12:15:10 -0400 Subject: [PATCH 2/5] add tests for FindName(), FindVersion(), FindNameGlobbing() scenarios --- .../FindPSResourceV2Server.Tests.ps1 | 14 ++++++++++++++ .../InstallPSResourceV2Server.Tests.ps1 | 10 ++++++++++ 2 files changed, 24 insertions(+) diff --git a/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 b/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 index 2a01c7677..be7a29ecc 100644 --- a/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 +++ b/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 @@ -457,4 +457,18 @@ Describe 'Test HTTP Find-PSResource for V2 Server Protocol' -tags 'ManualValidat $duplicatePkgsFound | Should -BeFalse } + + It "find should return an unlisted module when it was requested explicitly by full name and version (i.e no wildcards)" { + # 'test_unlisted' is an unlisted package + $res = Find-PSResource -Name "test_unlisted" -Version "0.0.1" -Repository $PSGalleryName + $res | Should -Not -BeNullOrEmpty + $res.Version | Should -Be "0.0.1" + } + + It "find should not return an unlisted module with it was requested with wildcards in the name" { + # 'test_unlisted' is an unlisted package whereas 'test_notunlisted' is listed + $res = Find-PSResource -Name "test_*unlisted" -Repository $PSGalleryName + $res.Count | Should -Be 1 + $res[0].Name | Should -Be "test_notunlisted" + } } diff --git a/test/InstallPSResourceTests/InstallPSResourceV2Server.Tests.ps1 b/test/InstallPSResourceTests/InstallPSResourceV2Server.Tests.ps1 index 0b03a984b..ed7ee73a1 100644 --- a/test/InstallPSResourceTests/InstallPSResourceV2Server.Tests.ps1 +++ b/test/InstallPSResourceTests/InstallPSResourceV2Server.Tests.ps1 @@ -573,6 +573,16 @@ Describe 'Test Install-PSResource for V2 Server scenarios' -tags 'CI' { $res | Should -Not -BeNullOrEmpty $res.Version | Should -Be $version } + + It "Install resource that is unlisted" { + # 'test_unlisted' is an unlisted package + $moduleName = 'test_unlisted' + $version = '0.0.1' + Install-PSResource -Name $moduleName -Repository $PSGalleryName -TrustRepository + $res = Get-InstalledPSResource $moduleName + $res | Should -Not -BeNullOrEmpty + $res.Version | Should -Be $version + } } Describe 'Test Install-PSResource for V2 Server scenarios' -tags 'ManualValidationOnly' { From 8b5b5091f43a1db2b2060b0f5c36839911b7c892 Mon Sep 17 00:00:00 2001 From: anamnavi Date: Thu, 21 Aug 2025 12:16:09 -0400 Subject: [PATCH 3/5] update tests --- .../FindPSResourceV2Server.Tests.ps1 | 34 +++++++++++++++---- .../InstallPSResourceV2Server.Tests.ps1 | 9 ++--- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 b/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 index be7a29ecc..59f526c0c 100644 --- a/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 +++ b/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 @@ -458,17 +458,39 @@ Describe 'Test HTTP Find-PSResource for V2 Server Protocol' -tags 'ManualValidat $duplicatePkgsFound | Should -BeFalse } - It "find should return an unlisted module when it was requested explicitly by full name and version (i.e no wildcards)" { - # 'test_unlisted' is an unlisted package - $res = Find-PSResource -Name "test_unlisted" -Version "0.0.1" -Repository $PSGalleryName + It "find should not return a module that has all unlisted versions, given full name and no version (i.e non wildcard name)" { + # FindName() scenario + # 'test_completelyunlisted' only has version 0.0.1, which is unlisted + $res = Find-PSResource -Name "test_completelyunlisted" -Repository $PSGalleryName + $res | Should -BeNullOrEmpty + $err.Count | Should -BeGreaterThan 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "PackageNotFound,Microsoft.PowerShell.PSResourceGet.Cmdlets.FindPSResource" + $res | Should -BeNullOrEmpty + } + + It "find should return a module version even if all versions are unlisted, given full name and version (i.e non wildcard name)" { + # FindVersion() scenario + # test_completelyunlisted has 1 version, 0.0.1, which is unlisted + $res = Find-PSResource -Name "test_completelyunlisted" -Version "0.0.1" -Repository $PSGalleryName $res | Should -Not -BeNullOrEmpty $res.Version | Should -Be "0.0.1" } + It "find should return an unlisted module, where the module has a mix of listed and unlisted versions, given full name and version (i.e non wildcard name)" { + # FindVersion scenario + # 'test_unlisted' version 0.0.3 is unlisted + $res = Find-PSResource -Name "test_unlisted" -Version "0.0.3" -Repository $PSGalleryName + $res | Should -Not -BeNullOrEmpty + $res.Version | Should -Be "0.0.3" + } + It "find should not return an unlisted module with it was requested with wildcards in the name" { - # 'test_unlisted' is an unlisted package whereas 'test_notunlisted' is listed + # FindNameGlobbing() scenario + # 'test_completelyunlisted' has all unlisted versions -> should not be returned + # whereas 'test_unlisted' has a listed verison and 'test_notunlisted' has all listed versions -> should be returned $res = Find-PSResource -Name "test_*unlisted" -Repository $PSGalleryName - $res.Count | Should -Be 1 - $res[0].Name | Should -Be "test_notunlisted" + $res.Count | Should -Be 2 + $res.Name | Should -Contain 'test_unlisted' + $res.Name | Should -Contain 'test_notunlisted' } } diff --git a/test/InstallPSResourceTests/InstallPSResourceV2Server.Tests.ps1 b/test/InstallPSResourceTests/InstallPSResourceV2Server.Tests.ps1 index ed7ee73a1..e7f02fcc3 100644 --- a/test/InstallPSResourceTests/InstallPSResourceV2Server.Tests.ps1 +++ b/test/InstallPSResourceTests/InstallPSResourceV2Server.Tests.ps1 @@ -574,11 +574,12 @@ Describe 'Test Install-PSResource for V2 Server scenarios' -tags 'CI' { $res.Version | Should -Be $version } - It "Install resource that is unlisted" { - # 'test_unlisted' is an unlisted package + It "Install resource that is unlisted" { + # InstallVersion scenario + # 'test_unlisted' version 0.0.3 is unlisted $moduleName = 'test_unlisted' - $version = '0.0.1' - Install-PSResource -Name $moduleName -Repository $PSGalleryName -TrustRepository + $version = '0.0.3' + Install-PSResource -Name $moduleName -Version $version -Repository $PSGalleryName -TrustRepository $res = Get-InstalledPSResource $moduleName $res | Should -Not -BeNullOrEmpty $res.Version | Should -Be $version From 761f643eac15f528cbb1fe49967762c7d1f77fc0 Mon Sep 17 00:00:00 2001 From: anamnavi Date: Thu, 21 Aug 2025 13:31:32 -0400 Subject: [PATCH 4/5] remove old test --- .../FindPSResourceV2Server.Tests.ps1 | 74 +++++++++---------- 1 file changed, 33 insertions(+), 41 deletions(-) diff --git a/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 b/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 index 59f526c0c..2d4d34b52 100644 --- a/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 +++ b/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 @@ -12,7 +12,6 @@ Describe 'Test HTTP Find-PSResource for V2 Server Protocol' -tags 'CI' { BeforeAll{ $PSGalleryName = Get-PSGalleryName $testModuleName = "test_module" - $testModuleNameWithUnlistedVersion = "test_module10" $testScriptName = "test_script" $commandName = "Get-TargetResource" $dscResourceName = "SystemLocale" @@ -413,11 +412,40 @@ Describe 'Test HTTP Find-PSResource for V2 Server Protocol' -tags 'CI' { $err.Count | Should -Be 0 } - It "should not find and write error when finding package version that is unlisted" { - $res = Find-PSResource -Name $testModuleNameWithUnlistedVersion -Version "1.0.0.0" -Repository $PSGalleryName -ErrorVariable err -ErrorAction SilentlyContinue - $res | Should -HaveCount 0 - $err | Should -HaveCount 1 + It "find should not return a module that has all unlisted versions, given full name and no version (i.e non wildcard name)" { + # FindName() scenario + # 'test_completelyunlisted' only has version 0.0.1, which is unlisted + $res = Find-PSResource -Name "test_completelyunlisted" -Repository $PSGalleryName + $res | Should -BeNullOrEmpty + $err.Count | Should -BeGreaterThan 0 $err[0].FullyQualifiedErrorId | Should -BeExactly "PackageNotFound,Microsoft.PowerShell.PSResourceGet.Cmdlets.FindPSResource" + $res | Should -BeNullOrEmpty + } + + It "find should return a module version even if all versions are unlisted, given full name and version (i.e non wildcard name)" { + # FindVersion() scenario + # test_completelyunlisted has 1 version, 0.0.1, which is unlisted + $res = Find-PSResource -Name "test_completelyunlisted" -Version "0.0.1" -Repository $PSGalleryName + $res | Should -Not -BeNullOrEmpty + $res.Version | Should -Be "0.0.1" + } + + It "find should return an unlisted module, where the module has a mix of listed and unlisted versions, given full name and version (i.e non wildcard name)" { + # FindVersion scenario + # 'test_unlisted' version 0.0.3 is unlisted + $res = Find-PSResource -Name "test_unlisted" -Version "0.0.3" -Repository $PSGalleryName + $res | Should -Not -BeNullOrEmpty + $res.Version | Should -Be "0.0.3" + } + + It "find should not return an unlisted module with it was requested with wildcards in the name" { + # FindNameGlobbing() scenario + # 'test_completelyunlisted' has all unlisted versions -> should not be returned + # whereas 'test_unlisted' has a listed verison and 'test_notunlisted' has all listed versions -> should be returned + $res = Find-PSResource -Name "test_*unlisted" -Repository $PSGalleryName + $res.Count | Should -Be 2 + $res.Name | Should -Contain 'test_unlisted' + $res.Name | Should -Contain 'test_notunlisted' } } @@ -457,40 +485,4 @@ Describe 'Test HTTP Find-PSResource for V2 Server Protocol' -tags 'ManualValidat $duplicatePkgsFound | Should -BeFalse } - - It "find should not return a module that has all unlisted versions, given full name and no version (i.e non wildcard name)" { - # FindName() scenario - # 'test_completelyunlisted' only has version 0.0.1, which is unlisted - $res = Find-PSResource -Name "test_completelyunlisted" -Repository $PSGalleryName - $res | Should -BeNullOrEmpty - $err.Count | Should -BeGreaterThan 0 - $err[0].FullyQualifiedErrorId | Should -BeExactly "PackageNotFound,Microsoft.PowerShell.PSResourceGet.Cmdlets.FindPSResource" - $res | Should -BeNullOrEmpty - } - - It "find should return a module version even if all versions are unlisted, given full name and version (i.e non wildcard name)" { - # FindVersion() scenario - # test_completelyunlisted has 1 version, 0.0.1, which is unlisted - $res = Find-PSResource -Name "test_completelyunlisted" -Version "0.0.1" -Repository $PSGalleryName - $res | Should -Not -BeNullOrEmpty - $res.Version | Should -Be "0.0.1" - } - - It "find should return an unlisted module, where the module has a mix of listed and unlisted versions, given full name and version (i.e non wildcard name)" { - # FindVersion scenario - # 'test_unlisted' version 0.0.3 is unlisted - $res = Find-PSResource -Name "test_unlisted" -Version "0.0.3" -Repository $PSGalleryName - $res | Should -Not -BeNullOrEmpty - $res.Version | Should -Be "0.0.3" - } - - It "find should not return an unlisted module with it was requested with wildcards in the name" { - # FindNameGlobbing() scenario - # 'test_completelyunlisted' has all unlisted versions -> should not be returned - # whereas 'test_unlisted' has a listed verison and 'test_notunlisted' has all listed versions -> should be returned - $res = Find-PSResource -Name "test_*unlisted" -Repository $PSGalleryName - $res.Count | Should -Be 2 - $res.Name | Should -Contain 'test_unlisted' - $res.Name | Should -Contain 'test_notunlisted' - } } From 7c18db27fd6cb29a432306121110b3141f072b10 Mon Sep 17 00:00:00 2001 From: anamnavi Date: Mon, 25 Aug 2025 12:55:33 -0400 Subject: [PATCH 5/5] capture ErrorVariable in test --- test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 b/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 index 2d4d34b52..0206a9185 100644 --- a/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 +++ b/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 @@ -415,11 +415,10 @@ Describe 'Test HTTP Find-PSResource for V2 Server Protocol' -tags 'CI' { It "find should not return a module that has all unlisted versions, given full name and no version (i.e non wildcard name)" { # FindName() scenario # 'test_completelyunlisted' only has version 0.0.1, which is unlisted - $res = Find-PSResource -Name "test_completelyunlisted" -Repository $PSGalleryName + $res = Find-PSResource -Name "test_completelyunlisted" -Repository $PSGalleryName -ErrorVariable err $res | Should -BeNullOrEmpty $err.Count | Should -BeGreaterThan 0 $err[0].FullyQualifiedErrorId | Should -BeExactly "PackageNotFound,Microsoft.PowerShell.PSResourceGet.Cmdlets.FindPSResource" - $res | Should -BeNullOrEmpty } It "find should return a module version even if all versions are unlisted, given full name and version (i.e non wildcard name)" {