Skip to content

Commit

Permalink
Fix Azure DevOps nuget v2 feed download (PowerShell#1713)
Browse files Browse the repository at this point in the history
  • Loading branch information
o-l-a-v authored Oct 10, 2024
1 parent e3d0303 commit 25d8f49
Show file tree
Hide file tree
Showing 2 changed files with 275 additions and 11 deletions.
22 changes: 11 additions & 11 deletions src/code/V2ServerAPICalls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public V2ServerAPICalls (PSRepositoryInfo repository, PSCmdlet cmdletPassedIn, N
HttpClientHandler handler = new HttpClientHandler();
bool token = false;

if(networkCredential != null)
if(networkCredential != null)
{
token = String.Equals("token", networkCredential.UserName) ? true : false;
};
Expand All @@ -72,7 +72,7 @@ public V2ServerAPICalls (PSRepositoryInfo repository, PSCmdlet cmdletPassedIn, N
} else {

handler.Credentials = networkCredential;

_sessionClient = new HttpClient(handler);
};

Expand Down Expand Up @@ -359,7 +359,7 @@ public override FindResults FindName(string packageName, bool includePrerelease,
if (type != ResourceType.None) {
filterBuilder.AddCriterion(GetTypeFilterForRequest(type));
}

var requestUrlV2 = $"{Repository.Uri}/FindPackagesById()?{queryBuilder.BuildQueryString()}";
string response = HttpRequestCall(requestUrlV2, out errRecord);
if (errRecord != null)
Expand Down Expand Up @@ -424,7 +424,7 @@ public override FindResults FindNameWithTag(string packageName, string[] tags, b
}

var requestUrlV2 = $"{Repository.Uri}/FindPackagesById()?{queryBuilder.BuildQueryString()}";

string response = HttpRequestCall(requestUrlV2, out errRecord);
if (errRecord != null)
{
Expand Down Expand Up @@ -638,7 +638,7 @@ public override FindResults FindVersion(string packageName, string version, Reso
if (!_isJFrogRepo) {
filterBuilder.AddCriterion($"Id eq '{packageName}'");
}

filterBuilder.AddCriterion($"NormalizedVersion eq '{version}'");
if (type != ResourceType.None) {
filterBuilder.AddCriterion(GetTypeFilterForRequest(type));
Expand Down Expand Up @@ -694,7 +694,7 @@ public override FindResults FindVersionWithTag(string packageName, string versio
if (!_isJFrogRepo) {
filterBuilder.AddCriterion($"Id eq '{packageName}'");
}

filterBuilder.AddCriterion($"NormalizedVersion eq '{version}'");
if (type != ResourceType.None) {
filterBuilder.AddCriterion(GetTypeFilterForRequest(type));
Expand Down Expand Up @@ -943,7 +943,7 @@ private string FindTagFromEndpoint(string[] tags, bool includePrerelease, bool i
}

filterBuilder.AddCriterion($"substringof('PS{(isSearchingModule ? "Module" : "Script")}', Tags) eq true");

foreach (string tag in tags)
{
filterBuilder.AddCriterion($"substringof('{tag}', Tags) eq true");
Expand Down Expand Up @@ -987,7 +987,7 @@ private string FindCommandOrDscResource(string[] tags, bool includePrerelease, b
" ",
tags.Select(tag => $"tag:{tagPrefix}{tag}")
) + "'";


var requestUrlV2 = $"{Repository.Uri}/Search()?{queryBuilder.BuildQueryString()}";

Expand Down Expand Up @@ -1271,7 +1271,7 @@ private string FindVersionGlobbing(string packageName, VersionRange versionRange
if (!includePrerelease) {
filterBuilder.AddCriterion("IsPrerelease eq false");
}

// We need to explicitly add 'Id eq <packageName>' whenever $filter is used, otherwise arbitrary results are returned.

// If it's a JFrog repository do not include the Id filter portion since JFrog uses 'Title' instead of 'Id',
Expand All @@ -1283,7 +1283,7 @@ private string FindVersionGlobbing(string packageName, VersionRange versionRange
if (type == ResourceType.Script) {
filterBuilder.AddCriterion($"substringof('PS{type.ToString()}', Tags) eq true");
}


var requestUrlV2 = $"{Repository.Uri}/FindPackagesById()?{queryBuilder.BuildQueryString()}";

Expand All @@ -1306,7 +1306,7 @@ private Stream InstallVersion(string packageName, string version, out ErrorRecor
if (_isADORepo)
{
// eg: https://pkgs.dev.azure.com/<org>/<project>/_packaging/<feed>/nuget/v2?id=test_module&version=5.0.0
requestUrlV2 = $"{Repository.Uri}?id={packageName}&version={version}";
requestUrlV2 = $"{Repository.Uri}?id={packageName.ToLower()}&version={version}";
}
else if (_isJFrogRepo)
{
Expand Down
264 changes: 264 additions & 0 deletions test/InstallPSResourceTests/InstallPSResourceADOV2Server.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

$ProgressPreference = "SilentlyContinue"
$modPath = "$psscriptroot/../PSGetTestUtils.psm1"
Import-Module $modPath -Force -Verbose

Describe 'Test Install-PSResource for V3Server scenarios' -tags 'CI' {

BeforeAll {
$testModuleName = "test_local_mod"
$testModuleName2 = "test_local_mod2"
$testScriptName = "test_ado_script"
$ADORepoName = "PSGetTestingPublicFeed"
$ADORepoUri = "https://pkgs.dev.azure.com/powershell/PowerShell/_packaging/psresourceget-public-test-ci/nuget/v2"
Get-NewPSResourceRepositoryFile
Register-PSResourceRepository -Name $ADORepoName -Uri $ADORepoUri
}

AfterEach {
Uninstall-PSResource $testModuleName, $testModuleName2, $testScriptName -Version "*" -SkipDependencyCheck -ErrorAction SilentlyContinue
}

AfterAll {
Get-RevertPSResourceRepositoryFile
}

$testCases = @{Name="*"; ErrorId="NameContainsWildcard"},
@{Name="Test_local_m*"; ErrorId="NameContainsWildcard"},
@{Name="Test?local","Test[local"; ErrorId="ErrorFilteringNamesForUnsupportedWildcards"}

It "Should not install resource with wildcard in name" -TestCases $testCases {
param($Name, $ErrorId)
Install-PSResource -Name $Name -Repository $ADORepoName -ErrorVariable err -ErrorAction SilentlyContinue
$err.Count | Should -BeGreaterThan 0
$err[0].FullyQualifiedErrorId | Should -BeExactly "$ErrorId,Microsoft.PowerShell.PSResourceGet.Cmdlets.InstallPSResource"
$res = Get-InstalledPSResource $testModuleName
$res | Should -BeNullOrEmpty
}

It "Install specific module resource by name" {
Install-PSResource -Name $testModuleName -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.Version | Should -Be "5.0.0"
}

It "Install specific script resource by name" {
Install-PSResource -Name $testScriptName -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $testScriptName
$pkg.Name | Should -Be $testScriptName
$pkg.Version | Should -Be "1.0.0"
}

It "Install multiple resources by name" {
$pkgNames = @($testModuleName, $testModuleName2)
Install-PSResource -Name $pkgNames -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $pkgNames
$pkg.Name | Should -Be $pkgNames
}

It "Should not install resource given nonexistant name" {
Install-PSResource -Name "NonExistantModule" -Repository $ADORepoName -TrustRepository -ErrorVariable err -ErrorAction SilentlyContinue
$pkg = Get-InstalledPSResource "NonExistantModule"
$pkg | Should -BeNullOrEmpty
$err.Count | Should -BeGreaterThan 0
$err[0].FullyQualifiedErrorId | Should -BeExactly "InstallPackageFailure,Microsoft.PowerShell.PSResourceGet.Cmdlets.InstallPSResource"
}

# Do some version testing, but Find-PSResource should be doing thorough testing
It "Should install resource given name and exact version" {
Install-PSResource -Name $testModuleName -Version "1.0.0" -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.Version | Should -Be "1.0.0"
}

It "Should install resource given name and exact version with bracket syntax" {
Install-PSResource -Name $testModuleName -Version "[1.0.0]" -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.Version | Should -Be "1.0.0"
}

It "Should install resource given name and exact range inclusive [1.0.0, 5.0.0]" {
Install-PSResource -Name $testModuleName -Version "[1.0.0, 5.0.0]" -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.Version | Should -Be "5.0.0"
}

It "Should install resource given name and exact range exclusive (1.0.0, 5.0.0)" {
Install-PSResource -Name $testModuleName -Version "(1.0.0, 5.0.0)" -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.Version | Should -Be "3.0.0"
}

# TODO: Update this test and others like it that use try/catch blocks instead of Should -Throw
It "Should not install resource with incorrectly formatted version such as exclusive version (1.0.0.0)" {
$Version = "(1.0.0.0)"
try {
Install-PSResource -Name $testModuleName -Version $Version -Repository $ADORepoName -TrustRepository -ErrorAction SilentlyContinue
}
catch
{}
$Error[0].FullyQualifiedErrorId | Should -be "IncorrectVersionFormat,Microsoft.PowerShell.PSResourceGet.Cmdlets.InstallPSResource"

$res = Get-InstalledPSResource $testModuleName
$res | Should -BeNullOrEmpty
}

It "Install resource when given Name, Version '*', should install the latest version" {
Install-PSResource -Name $testModuleName -Version "*" -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.Version | Should -Be "5.0.0"
}

It "Install resource with latest (including prerelease) version given Prerelease parameter" {
Install-PSResource -Name $testModuleName -Prerelease -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.Version | Should -Be "5.2.5"
$pkg.Prerelease | Should -Be "alpha001"
}

It "Install resource via InputObject by piping from Find-PSresource" {
Find-PSResource -Name $testModuleName -Repository $ADORepoName | Install-PSResource -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.Version | Should -Be "5.0.0"
}

It "Install resource with companyname and repository source location and validate properties" {
Install-PSResource -Name $testModuleName -Version "5.2.5-alpha001" -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Version | Should -Be "5.2.5"
$pkg.Prerelease | Should -Be "alpha001"

$pkg.CompanyName | Should -Be "None"
$pkg.RepositorySourceLocation | Should -Be $ADORepoUri
}

# Windows only
It "Install resource under CurrentUser scope - Windows only" -Skip:(!(Get-IsWindows)) {
Install-PSResource -Name $testModuleName -Repository $ADORepoName -TrustRepository -Scope CurrentUser
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.InstalledLocation.ToString().Contains("Documents") | Should -Be $true
}

# Windows only
It "Install resource under AllUsers scope - Windows only" -Skip:(!((Get-IsWindows) -and (Test-IsAdmin))) {
Install-PSResource -Name $testModuleName -Repository $ADORepoName -TrustRepository -Scope AllUsers -Verbose
$pkg = Get-InstalledPSResource $testModuleName -Scope AllUsers
$pkg.Name | Should -Be $testModuleName
$pkg.InstalledLocation.ToString().Contains("Program Files") | Should -Be $true
}

# Windows only
It "Install resource under no specified scope - Windows only" -Skip:(!(Get-IsWindows)) {
Install-PSResource -Name $testModuleName -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.InstalledLocation.ToString().Contains("Documents") | Should -Be $true
}

# Unix only
# Expected path should be similar to: '/home/janelane/.local/share/powershell/Modules'
It "Install resource under CurrentUser scope - Unix only" -Skip:(Get-IsWindows) {
Install-PSResource -Name $testModuleName -Repository $ADORepoName -TrustRepository -Scope CurrentUser
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.InstalledLocation.ToString().Contains("$env:HOME/.local") | Should -Be $true
}

# Unix only
# Expected path should be similar to: '/home/janelane/.local/share/powershell/Modules'
It "Install resource under no specified scope - Unix only" -Skip:(Get-IsWindows) {
Install-PSResource -Name $testModuleName -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.InstalledLocation.ToString().Contains("$env:HOME/.local") | Should -Be $true
}

It "Should not install resource that is already installed" {
Install-PSResource -Name $testModuleName -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
Install-PSResource -Name $testModuleName -Repository $ADORepoName -TrustRepository -WarningVariable WarningVar -warningaction SilentlyContinue
$WarningVar | Should -Not -BeNullOrEmpty
}

It "Reinstall resource that is already installed with -Reinstall parameter" {
Install-PSResource -Name $testModuleName -Repository $ADORepoName -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.Version | Should -Be "5.0.0"
Install-PSResource -Name $testModuleName -Repository $ADORepoName -Reinstall -TrustRepository
$pkg = Get-InstalledPSResource $testModuleName
$pkg.Name | Should -Be $testModuleName
$pkg.Version | Should -Be "5.0.0"
}

It "Install PSResourceInfo object piped in" {
Find-PSResource -Name $testModuleName -Version "1.0.0.0" -Repository $ADORepoName | Install-PSResource -TrustRepository
$res = Get-InstalledPSResource -Name $testModuleName
$res.Name | Should -Be $testModuleName
$res.Version | Should -Be "1.0.0"
}

It "Install module using -PassThru" {
$res = Install-PSResource -Name $testModuleName -Repository $ADORepoName -PassThru -TrustRepository
$res.Name | Should -Contain $testModuleName
}
}

Describe 'Test Install-PSResource for V3Server scenarios' -tags 'ManualValidationOnly' {

BeforeAll {
$testModuleName = "TestModule"
$testModuleName2 = "testModuleWithlicense"
Get-NewPSResourceRepositoryFile
Register-LocalRepos
}

AfterEach {
Uninstall-PSResource $testModuleName, $testModuleName2 -SkipDependencyCheck -ErrorAction SilentlyContinue
}

AfterAll {
Get-RevertPSResourceRepositoryFile
}

# Unix only manual test
# Expected path should be similar to: '/usr/local/share/powershell/Modules'
It "Install resource under AllUsers scope - Unix only" -Skip:(Get-IsWindows) {
Install-PSResource -Name $testModuleName -Repository $TestGalleryName -Scope AllUsers
$pkg = Get-Module $testModuleName -ListAvailable
$pkg.Name | Should -Be $testModuleName
$pkg.Path.Contains("/usr/") | Should -Be $true
}

# This needs to be manually tested due to prompt
It "Install resource that requires accept license without -AcceptLicense flag" {
Install-PSResource -Name $testModuleName2 -Repository $TestGalleryName
$pkg = Get-InstalledPSResource $testModuleName2
$pkg.Name | Should -Be $testModuleName2
$pkg.Version | Should -Be "0.0.1.0"
}

# This needs to be manually tested due to prompt
It "Install resource should prompt 'trust repository' if repository is not trusted" {
Set-PSResourceRepository PoshTestGallery -Trusted:$false

Install-PSResource -Name $testModuleName -Repository $TestGalleryName -confirm:$false

$pkg = Get-Module $testModuleName -ListAvailable
$pkg.Name | Should -Be $testModuleName

Set-PSResourceRepository PoshTestGallery -Trusted
}
}

0 comments on commit 25d8f49

Please sign in to comment.