From 4debd4622e98ab69259f707791a2e83e71ff2668 Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Fri, 12 Jul 2024 13:29:33 -0700 Subject: [PATCH 01/14] (maint) Convert common string to constant --- src/chocolatey/StringResources.cs | 7 +++++++ src/chocolatey/infrastructure.app/services/NugetService.cs | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/chocolatey/StringResources.cs b/src/chocolatey/StringResources.cs index 8f04a3e641..92950f39fe 100644 --- a/src/chocolatey/StringResources.cs +++ b/src/chocolatey/StringResources.cs @@ -56,5 +56,12 @@ public static class EnvironmentVariables [Browsable(false)] internal const string PackageNuspecVersion = "packageNuspecVersion"; } + + public static class ErrorMessages + { + [EditorBrowsable(EditorBrowsableState.Never)] + [Browsable(false)] + internal const string UnableToDowngrade = "A newer version of {0} (v{1}) is already installed.{2} Use --allow-downgrade or --force to attempt to install older versions."; + } } } \ No newline at end of file diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index 8b74d713ae..00306421a7 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -619,7 +619,7 @@ public virtual ConcurrentDictionary Install(ChocolateyCon if (installedPackage != null && version != null && version < installedPackage.PackageMetadata.Version && !config.AllowDowngrade) { - var logMessage = "A newer version of {0} (v{1}) is already installed.{2} Use --allow-downgrade or --force to attempt to install older versions.".FormatWith(installedPackage.Name, installedPackage.Version, Environment.NewLine); + var logMessage = StringResources.ErrorMessages.UnableToDowngrade.FormatWith(installedPackage.Name, installedPackage.Version, Environment.NewLine); var nullResult = packageResultsToReturn.GetOrAdd(packageName, installedPackage); nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); @@ -1138,7 +1138,7 @@ public virtual ConcurrentDictionary Upgrade(ChocolateyCon if (version != null && version < installedPackage.PackageMetadata.Version && !config.AllowDowngrade) { - var logMessage = "A newer version of {0} (v{1}) is already installed.{2} Use --allow-downgrade or --force to attempt to upgrade to older versions.".FormatWith(installedPackage.PackageMetadata.Id, installedPackage.Version, Environment.NewLine); + var logMessage = StringResources.ErrorMessages.UnableToDowngrade.FormatWith(installedPackage.PackageMetadata.Id, installedPackage.Version, Environment.NewLine); var nullResult = packageResultsToReturn.GetOrAdd(packageName, new PackageResult(installedPackage.PackageMetadata, pathResolver.GetInstallPath(installedPackage.PackageMetadata.Id))); nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); From d660ca50b2ba1216eab81998086ba2a3e04b1049 Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Thu, 11 Jul 2024 12:48:26 -0700 Subject: [PATCH 02/14] (#3461) Prevent downgrade of dependency --- .../services/NugetService.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index 00306421a7..568be108e7 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -809,6 +809,16 @@ Version was specified as '{0}'. It is possible that version var packageToUninstall = packagesToUninstall.FirstOrDefault(p => p.PackageMetadata.Id.Equals(packageDependencyInfo.Id, StringComparison.OrdinalIgnoreCase)); if (packageToUninstall != null) { + // Are we attempting a downgrade? We need to ensure it's allowed... + if (!config.AllowDowngrade && packageToUninstall.Identity.HasVersion && packageDependencyInfo.HasVersion && packageDependencyInfo.Version < packageToUninstall.Identity.Version) + { + var logMessage = StringResources.ErrorMessages.UnableToDowngrade.FormatWith(packageToUninstall.Name, packageToUninstall.Version, Environment.NewLine); + var nullResult = packageResultsToReturn.GetOrAdd(packageToUninstall.Name, packageToUninstall); + nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); + this.Log().Error(ChocolateyLoggers.Important, logMessage); + continue; + } + shouldAddForcedResultMessage = true; BackupAndRunBeforeModify(packageToUninstall, config, beforeModifyAction); packageToUninstall.InstallLocation = pathResolver.GetInstallPath(packageToUninstall.Identity); @@ -1576,6 +1586,16 @@ public virtual ConcurrentDictionary Upgrade(ChocolateyCon { if (packageToUninstall != null) { + // Are we attempting a downgrade? We need to ensure it's allowed... + if (!config.AllowDowngrade && packageToUninstall.Identity.HasVersion && packageDependencyInfo.HasVersion && packageDependencyInfo.Version < packageToUninstall.Identity.Version) + { + var logMessage = StringResources.ErrorMessages.UnableToDowngrade.FormatWith(packageToUninstall.Name, packageToUninstall.Version, Environment.NewLine); + var nullResult = packageResultsToReturn.GetOrAdd(packageToUninstall.Name, packageToUninstall); + nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); + this.Log().Error(ChocolateyLoggers.Important, logMessage); + continue; + } + var oldPkgInfo = _packageInfoService.Get(packageToUninstall.PackageMetadata); BackupAndRunBeforeModify(packageToUninstall, oldPkgInfo, config, beforeUpgradeAction); From f9113827d73de52a538647f5cb5f92218345a43b Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Mon, 15 Jul 2024 08:23:17 -0700 Subject: [PATCH 03/14] (#3487) Prevent package success on dependency fail When a package dependency fails to install, we will now fail the package as well. --- src/chocolatey/StringResources.cs | 1 + .../services/NugetService.cs | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/chocolatey/StringResources.cs b/src/chocolatey/StringResources.cs index 92950f39fe..e28c11eb75 100644 --- a/src/chocolatey/StringResources.cs +++ b/src/chocolatey/StringResources.cs @@ -62,6 +62,7 @@ public static class ErrorMessages [EditorBrowsable(EditorBrowsableState.Never)] [Browsable(false)] internal const string UnableToDowngrade = "A newer version of {0} (v{1}) is already installed.{2} Use --allow-downgrade or --force to attempt to install older versions."; + internal const string DependencyFailedToInstall = "Failed to install {0} because a previous dependency failed."; } } } \ No newline at end of file diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index 568be108e7..03ed7e4fb6 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -578,6 +578,12 @@ public virtual ConcurrentDictionary Install(ChocolateyCon foreach (var packageName in packageNames.OrEmpty()) { + if (packageResultsToReturn.ContainsKey(packageName)) + { + // We have already processed this package (likely during dependency resolution of another package). + continue; + } + // We need to ensure we are using a clean configuration file // before we start reading it. config.RevertChanges(); @@ -793,6 +799,23 @@ Version was specified as '{0}'. It is possible that version foreach (SourcePackageDependencyInfo packageDependencyInfo in resolvedPackages) { + // Don't attempt to action this package if dependencies failed. + if (packageDependencyInfo != null && packageResultsToReturn.Any(r => r.Value.Success != true && packageDependencyInfo.Dependencies.Any(d => d.Id == r.Value.Identity.Id))) + { + var logMessage = StringResources.ErrorMessages.DependencyFailedToInstall.FormatWith(packageDependencyInfo.Id); + var x = new PackageResult(packageDependencyInfo.Id, packageDependencyInfo.Version.ToStringSafe(), string.Empty); + var nullResult = packageResultsToReturn.GetOrAdd(packageDependencyInfo.Id, x); + nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); + this.Log().Error(ChocolateyLoggers.Important, logMessage); + + if (config.Features.StopOnFirstPackageFailure) + { + throw new ApplicationException("Stopping further execution as {0} has failed install.".FormatWith(packageDependencyInfo.Id)); + } + + continue; + } + var packageRemoteMetadata = packagesToInstall.FirstOrDefault(p => p.Identity.Equals(packageDependencyInfo)); if (packageRemoteMetadata is null) @@ -816,6 +839,12 @@ Version was specified as '{0}'. It is possible that version var nullResult = packageResultsToReturn.GetOrAdd(packageToUninstall.Name, packageToUninstall); nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); + + if (config.Features.StopOnFirstPackageFailure) + { + throw new ApplicationException("Stopping further execution as {0} has failed install.".FormatWith(packageToUninstall.Identity.Id)); + } + continue; } @@ -1061,6 +1090,12 @@ public virtual ConcurrentDictionary Upgrade(ChocolateyCon foreach (var packageName in config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries).OrEmpty()) { + if (packageResultsToReturn.ContainsKey(packageName)) + { + // We have already processed this package (likely during dependency resolution of another package). + continue; + } + // We need to ensure we are using a clean configuration file // before we start reading it. config.RevertChanges(); @@ -1569,6 +1604,23 @@ public virtual ConcurrentDictionary Upgrade(ChocolateyCon break; } + // Don't attempt to action this package if dependencies failed. + if (packageResultsToReturn.Any(r => r.Value.Success != true && packageDependencyInfo.Dependencies.Any(d => d.Id == r.Value.Identity.Id))) + { + var logMessage = StringResources.ErrorMessages.DependencyFailedToInstall.FormatWith(packageDependencyInfo.Id, packageDependencyInfo.Version); + var x = new PackageResult(packageDependencyInfo.Id, packageDependencyInfo.Version.ToStringSafe(), string.Empty); + var nullResult = packageResultsToReturn.GetOrAdd(packageDependencyInfo.Id, x); + nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); + this.Log().Error(ChocolateyLoggers.Important, logMessage); + + if (config.Features.StopOnFirstPackageFailure) + { + throw new ApplicationException("Stopping further execution as {0} has failed.".FormatWith(packageDependencyInfo.Id)); + } + + continue; + } + var packageRemoteMetadata = packagesToInstall.FirstOrDefault(p => p.Identity.Equals(packageDependencyInfo)); if (packageRemoteMetadata is null) @@ -1593,9 +1645,25 @@ public virtual ConcurrentDictionary Upgrade(ChocolateyCon var nullResult = packageResultsToReturn.GetOrAdd(packageToUninstall.Name, packageToUninstall); nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); + + if (config.Features.StopOnFirstPackageFailure) + { + throw new ApplicationException("Stopping further execution as {0} has failed.".FormatWith(packageDependencyInfo.Id)); + } + continue; } + // Package was previously marked inconclusive (not upgraded). We need remove the message since we are now upgrading it. + // Packages that are inconclusive but successfull are not labeled as successful at the end of the run. + var checkResult = packageResultsToReturn.GetOrAdd(packageToUninstall.Name, packageToUninstall); + + while (checkResult.Inconclusive) + { + checkResult.Messages.Remove(checkResult.Messages.FirstOrDefault((m) => m.MessageType == ResultType.Inconclusive)); + } + + var oldPkgInfo = _packageInfoService.Get(packageToUninstall.PackageMetadata); BackupAndRunBeforeModify(packageToUninstall, oldPkgInfo, config, beforeUpgradeAction); From 522d5207f25d5f386ca39cc43a10a44958029f49 Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Mon, 15 Jul 2024 14:51:55 -0700 Subject: [PATCH 04/14] (#3461) Add downgrade install pester test --- .../commands/choco-install.Tests.ps1 | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/tests/pester-tests/commands/choco-install.Tests.ps1 b/tests/pester-tests/commands/choco-install.Tests.ps1 index 9cfa0f1a95..3b1c075fa5 100644 --- a/tests/pester-tests/commands/choco-install.Tests.ps1 +++ b/tests/pester-tests/commands/choco-install.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "choco install" -Tag Chocolatey, InstallCommand { +Describe "choco install" -Tag Chocolatey, InstallCommand { BeforeDiscovery { $isLicensed30OrMissingVersion = Test-PackageIsEqualOrHigher 'chocolatey.extension' '3.0.0-beta' -AllowMissingPackage $licensedProxyFixed = Test-PackageIsEqualOrHigher 'chocolatey.extension' 2.2.0-beta -AllowMissingPackage @@ -2070,6 +2070,54 @@ To install a local, or remote file, you may use: } } + Context 'Installing a package should not downgrade an existing package dependency.' -Tag Downgrade { + BeforeAll { + $DependentPackage = @{ + Name = 'isexactversiondependency' + Version = '2.0.0' + } + + Restore-ChocolateyInstallSnapshot + + $Setup = Invoke-Choco install $DependentPackage.Name --version $DependentPackage.Version --confirm + $Output = Invoke-Choco install toplevelhasexactversiondependency + } + + It "Exits with Failure (1)" { + $Output.ExitCode | Should -Be 1 -Because $Output.String + } + + It "Reports that it cannot downgrade isexactversiondependency" { + $Output.Lines | Should -Contain 'A newer version of isexactversiondependency (v2.0.0) is already installed.' -Because $Output.String + $Output.Lines | Should -Contain 'Use --allow-downgrade or --force to attempt to install older versions.' -Because $Output.String + $Output.Lines | Should -Contain 'Chocolatey installed 0/3 packages. 3 packages failed.' -Because $Output.String + } + } + + Context 'Installing a package should downgrade an existing package dependency when <_> is used.' -ForEach @('--force', '--allow-downgrade') -Tag Downgrade { + BeforeAll { + $DependentPackage = @{ + Name = 'isexactversiondependency' + Version = '2.0.0' + } + + Restore-ChocolateyInstallSnapshot + + $Setup = Invoke-Choco install $DependentPackage.Name --version $DependentPackage.Version --confirm + $Output = Invoke-Choco install toplevelhasexactversiondependency $_ + } + + It "Exits with Success (0)" { + $Output.ExitCode | Should -Be 0 -Because $Output.String + } + + It "Does not report that it cannot downgrade isexactversiondependency" { + $Output.Lines | Should -Not -Contain 'A newer version of isexactversiondependency (v2.0.0) is already installed.' -Because $Output.String + $Output.Lines | Should -Not -Contain 'Use --allow-downgrade or --force to attempt to install older versions.' -Because $Output.String + $Output.Lines | Should -Contain 'Chocolatey installed 3/3 packages.' -Because $Output.String + } + } + # This needs to be the last test in this block, to ensure NuGet configurations aren't being created. # Any tests after this block are expected to generate the configuration as they're explicitly using the NuGet CLI Test-NuGetPaths From 4a8479e670ce7acd3aad62e4b85515f644063dc2 Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Thu, 15 Aug 2024 09:38:24 -0700 Subject: [PATCH 05/14] (#3461,#3487) Add test packages for added tests Some of these package already existed on our internal repository, while some of them have been added for the tests being added. --- .../dependencyfailure.nuspec | 19 +++++++++++++++ .../tools/chocolateyinstall.ps1 | 1 + .../failingdependency.nuspec | 16 +++++++++++++ .../tools/chocolateyinstall.ps1 | 3 +++ .../1.0.0/hasfailingnesteddependency.nuspec | 23 +++++++++++++++++++ .../1.0.0/tools/chocolateyinstall.ps1 | 1 + .../1.0.0/tools/chocolateyuninstall.ps1 | 1 + .../1.0.0/hasnesteddependency.nuspec | 22 ++++++++++++++++++ .../1.0.0/tools/chocolateyinstall.ps1 | 1 + .../1.0.0/tools/chocolateyuninstall.ps1 | 1 + .../1.0.0/downgradesdependency.nuspec | 22 ++++++++++++++++++ .../1.0.0/tools/chocolateybeforemodify.ps1 | 1 + .../1.0.0/tools/chocolateyinstall.ps1 | 1 + .../1.0.0/tools/chocolateyuninstall.ps1 | 1 + .../1.0.0/upgradedowngradesdependency.nuspec | 22 ++++++++++++++++++ .../2.0.0/downgradesdependency.nuspec | 22 ++++++++++++++++++ .../2.0.0/tools/chocolateybeforemodify.ps1 | 1 + .../2.0.0/tools/chocolateyinstall.ps1 | 1 + .../2.0.0/tools/chocolateyuninstall.ps1 | 1 + .../2.0.0/upgradedowngradesdependency.nuspec | 22 ++++++++++++++++++ .../upgradedowngradesdependency/Readme.md | 6 +++++ 21 files changed, 188 insertions(+) create mode 100644 tests/packages/dependencyfailure/dependencyfailure.nuspec create mode 100644 tests/packages/dependencyfailure/tools/chocolateyinstall.ps1 create mode 100644 tests/packages/failingdependency/failingdependency.nuspec create mode 100644 tests/packages/failingdependency/tools/chocolateyinstall.ps1 create mode 100644 tests/packages/hasfailingnesteddependency/1.0.0/hasfailingnesteddependency.nuspec create mode 100644 tests/packages/hasfailingnesteddependency/1.0.0/tools/chocolateyinstall.ps1 create mode 100644 tests/packages/hasfailingnesteddependency/1.0.0/tools/chocolateyuninstall.ps1 create mode 100644 tests/packages/hasnesteddependency/1.0.0/hasnesteddependency.nuspec create mode 100644 tests/packages/hasnesteddependency/1.0.0/tools/chocolateyinstall.ps1 create mode 100644 tests/packages/hasnesteddependency/1.0.0/tools/chocolateyuninstall.ps1 create mode 100644 tests/packages/upgradedowngradesdependency/1.0.0/downgradesdependency.nuspec create mode 100644 tests/packages/upgradedowngradesdependency/1.0.0/tools/chocolateybeforemodify.ps1 create mode 100644 tests/packages/upgradedowngradesdependency/1.0.0/tools/chocolateyinstall.ps1 create mode 100644 tests/packages/upgradedowngradesdependency/1.0.0/tools/chocolateyuninstall.ps1 create mode 100644 tests/packages/upgradedowngradesdependency/1.0.0/upgradedowngradesdependency.nuspec create mode 100644 tests/packages/upgradedowngradesdependency/2.0.0/downgradesdependency.nuspec create mode 100644 tests/packages/upgradedowngradesdependency/2.0.0/tools/chocolateybeforemodify.ps1 create mode 100644 tests/packages/upgradedowngradesdependency/2.0.0/tools/chocolateyinstall.ps1 create mode 100644 tests/packages/upgradedowngradesdependency/2.0.0/tools/chocolateyuninstall.ps1 create mode 100644 tests/packages/upgradedowngradesdependency/2.0.0/upgradedowngradesdependency.nuspec create mode 100644 tests/packages/upgradedowngradesdependency/Readme.md diff --git a/tests/packages/dependencyfailure/dependencyfailure.nuspec b/tests/packages/dependencyfailure/dependencyfailure.nuspec new file mode 100644 index 0000000000..46f577f772 --- /dev/null +++ b/tests/packages/dependencyfailure/dependencyfailure.nuspec @@ -0,0 +1,19 @@ + + + + dependencyfailure + 1.0.0 + dependencyfailure (Install) + __REPLACE_AUTHORS_OF_SOFTWARE_COMMA_SEPARATED__ + https://_Software_Location_REMOVE_OR_FILL_OUT_ + dependencyfailure admin SPACE_SEPARATED + __REPLACE__ + __REPLACE__MarkDown_Okay + + + + + + + + diff --git a/tests/packages/dependencyfailure/tools/chocolateyinstall.ps1 b/tests/packages/dependencyfailure/tools/chocolateyinstall.ps1 new file mode 100644 index 0000000000..719bcd8ac7 --- /dev/null +++ b/tests/packages/dependencyfailure/tools/chocolateyinstall.ps1 @@ -0,0 +1 @@ +Write-Host "I'm successful!" \ No newline at end of file diff --git a/tests/packages/failingdependency/failingdependency.nuspec b/tests/packages/failingdependency/failingdependency.nuspec new file mode 100644 index 0000000000..66769fd42c --- /dev/null +++ b/tests/packages/failingdependency/failingdependency.nuspec @@ -0,0 +1,16 @@ + + + + failingdependency + 1.0.0 + dependencyfailure (Install) + __REPLACE_AUTHORS_OF_SOFTWARE_COMMA_SEPARATED__ + https://_Software_Location_REMOVE_OR_FILL_OUT_ + dependencyfailure admin SPACE_SEPARATED + __REPLACE__ + __REPLACE__MarkDown_Okay + + + + + diff --git a/tests/packages/failingdependency/tools/chocolateyinstall.ps1 b/tests/packages/failingdependency/tools/chocolateyinstall.ps1 new file mode 100644 index 0000000000..b14a38a512 --- /dev/null +++ b/tests/packages/failingdependency/tools/chocolateyinstall.ps1 @@ -0,0 +1,3 @@ +Write-Error "This should fail!" +$env:ChocolateyExitCode = '15608' +#throw "This is crap" \ No newline at end of file diff --git a/tests/packages/hasfailingnesteddependency/1.0.0/hasfailingnesteddependency.nuspec b/tests/packages/hasfailingnesteddependency/1.0.0/hasfailingnesteddependency.nuspec new file mode 100644 index 0000000000..3113e456a8 --- /dev/null +++ b/tests/packages/hasfailingnesteddependency/1.0.0/hasfailingnesteddependency.nuspec @@ -0,0 +1,23 @@ + + + + hasfailingnesteddependency + 1.0.0 + hasfailingnesteddependency + __REPLACE_AUTHORS_OF_SOFTWARE__ + __REPLACE_YOUR_NAME__ + false + __REPLACE__ + __REPLACE__ + + + hasfailingnesteddependency admin + + + + + + + + + diff --git a/tests/packages/hasfailingnesteddependency/1.0.0/tools/chocolateyinstall.ps1 b/tests/packages/hasfailingnesteddependency/1.0.0/tools/chocolateyinstall.ps1 new file mode 100644 index 0000000000..d64eb8f47b --- /dev/null +++ b/tests/packages/hasfailingnesteddependency/1.0.0/tools/chocolateyinstall.ps1 @@ -0,0 +1 @@ +Write-Output "$env:PackageName $env:PackageVersion Installed" \ No newline at end of file diff --git a/tests/packages/hasfailingnesteddependency/1.0.0/tools/chocolateyuninstall.ps1 b/tests/packages/hasfailingnesteddependency/1.0.0/tools/chocolateyuninstall.ps1 new file mode 100644 index 0000000000..9ead91ffa3 --- /dev/null +++ b/tests/packages/hasfailingnesteddependency/1.0.0/tools/chocolateyuninstall.ps1 @@ -0,0 +1 @@ +Write-Output "$env:PackageName $env:PackageVersion Uninstalled" \ No newline at end of file diff --git a/tests/packages/hasnesteddependency/1.0.0/hasnesteddependency.nuspec b/tests/packages/hasnesteddependency/1.0.0/hasnesteddependency.nuspec new file mode 100644 index 0000000000..6e3a0d1ec2 --- /dev/null +++ b/tests/packages/hasnesteddependency/1.0.0/hasnesteddependency.nuspec @@ -0,0 +1,22 @@ + + + + hasnesteddependency + 1.0.0 + hasnesteddependency + __REPLACE_AUTHORS_OF_SOFTWARE__ + __REPLACE_YOUR_NAME__ + false + __REPLACE__ + __REPLACE__ + + + hasnesteddependency admin + + + + + + + + diff --git a/tests/packages/hasnesteddependency/1.0.0/tools/chocolateyinstall.ps1 b/tests/packages/hasnesteddependency/1.0.0/tools/chocolateyinstall.ps1 new file mode 100644 index 0000000000..d64eb8f47b --- /dev/null +++ b/tests/packages/hasnesteddependency/1.0.0/tools/chocolateyinstall.ps1 @@ -0,0 +1 @@ +Write-Output "$env:PackageName $env:PackageVersion Installed" \ No newline at end of file diff --git a/tests/packages/hasnesteddependency/1.0.0/tools/chocolateyuninstall.ps1 b/tests/packages/hasnesteddependency/1.0.0/tools/chocolateyuninstall.ps1 new file mode 100644 index 0000000000..9ead91ffa3 --- /dev/null +++ b/tests/packages/hasnesteddependency/1.0.0/tools/chocolateyuninstall.ps1 @@ -0,0 +1 @@ +Write-Output "$env:PackageName $env:PackageVersion Uninstalled" \ No newline at end of file diff --git a/tests/packages/upgradedowngradesdependency/1.0.0/downgradesdependency.nuspec b/tests/packages/upgradedowngradesdependency/1.0.0/downgradesdependency.nuspec new file mode 100644 index 0000000000..dc187b1bec --- /dev/null +++ b/tests/packages/upgradedowngradesdependency/1.0.0/downgradesdependency.nuspec @@ -0,0 +1,22 @@ + + + + downgradesdependency + 1.0.0 + Has out of range Dependency + __REPLACE_AUTHORS_OF_SOFTWARE__ + __REPLACE_YOUR_NAME__ + false + __REPLACE__ + Package to test for out of range dependencies. This 1st version have a valid exact range. + + + upgradedowngradesdependency admin + + + + + + + + diff --git a/tests/packages/upgradedowngradesdependency/1.0.0/tools/chocolateybeforemodify.ps1 b/tests/packages/upgradedowngradesdependency/1.0.0/tools/chocolateybeforemodify.ps1 new file mode 100644 index 0000000000..7d0b91fece --- /dev/null +++ b/tests/packages/upgradedowngradesdependency/1.0.0/tools/chocolateybeforemodify.ps1 @@ -0,0 +1 @@ +Write-Output "Upgrading or Uninstalling $env:PackageName $env:PackageVersion" \ No newline at end of file diff --git a/tests/packages/upgradedowngradesdependency/1.0.0/tools/chocolateyinstall.ps1 b/tests/packages/upgradedowngradesdependency/1.0.0/tools/chocolateyinstall.ps1 new file mode 100644 index 0000000000..d64eb8f47b --- /dev/null +++ b/tests/packages/upgradedowngradesdependency/1.0.0/tools/chocolateyinstall.ps1 @@ -0,0 +1 @@ +Write-Output "$env:PackageName $env:PackageVersion Installed" \ No newline at end of file diff --git a/tests/packages/upgradedowngradesdependency/1.0.0/tools/chocolateyuninstall.ps1 b/tests/packages/upgradedowngradesdependency/1.0.0/tools/chocolateyuninstall.ps1 new file mode 100644 index 0000000000..9ead91ffa3 --- /dev/null +++ b/tests/packages/upgradedowngradesdependency/1.0.0/tools/chocolateyuninstall.ps1 @@ -0,0 +1 @@ +Write-Output "$env:PackageName $env:PackageVersion Uninstalled" \ No newline at end of file diff --git a/tests/packages/upgradedowngradesdependency/1.0.0/upgradedowngradesdependency.nuspec b/tests/packages/upgradedowngradesdependency/1.0.0/upgradedowngradesdependency.nuspec new file mode 100644 index 0000000000..829afd16f8 --- /dev/null +++ b/tests/packages/upgradedowngradesdependency/1.0.0/upgradedowngradesdependency.nuspec @@ -0,0 +1,22 @@ + + + + upgradedowngradesdependency + 1.0.0 + Has out of range Dependency + __REPLACE_AUTHORS_OF_SOFTWARE__ + __REPLACE_YOUR_NAME__ + false + __REPLACE__ + Package to test for out of range dependencies. This 1st version have a valid exact range. + + + upgradedowngradesdependency admin + + + + + + + + diff --git a/tests/packages/upgradedowngradesdependency/2.0.0/downgradesdependency.nuspec b/tests/packages/upgradedowngradesdependency/2.0.0/downgradesdependency.nuspec new file mode 100644 index 0000000000..817853880f --- /dev/null +++ b/tests/packages/upgradedowngradesdependency/2.0.0/downgradesdependency.nuspec @@ -0,0 +1,22 @@ + + + + downgradesdependency + 2.0.0 + Has out of range Dependency (Below available) + __REPLACE_AUTHORS_OF_SOFTWARE__ + __REPLACE_YOUR_NAME__ + false + __REPLACE__ + Package to test for out of range dependencies. This version uses a dependency that require a lower version. + + + upgradedowngradesdependency admin + + + + + + + + diff --git a/tests/packages/upgradedowngradesdependency/2.0.0/tools/chocolateybeforemodify.ps1 b/tests/packages/upgradedowngradesdependency/2.0.0/tools/chocolateybeforemodify.ps1 new file mode 100644 index 0000000000..7d0b91fece --- /dev/null +++ b/tests/packages/upgradedowngradesdependency/2.0.0/tools/chocolateybeforemodify.ps1 @@ -0,0 +1 @@ +Write-Output "Upgrading or Uninstalling $env:PackageName $env:PackageVersion" \ No newline at end of file diff --git a/tests/packages/upgradedowngradesdependency/2.0.0/tools/chocolateyinstall.ps1 b/tests/packages/upgradedowngradesdependency/2.0.0/tools/chocolateyinstall.ps1 new file mode 100644 index 0000000000..d64eb8f47b --- /dev/null +++ b/tests/packages/upgradedowngradesdependency/2.0.0/tools/chocolateyinstall.ps1 @@ -0,0 +1 @@ +Write-Output "$env:PackageName $env:PackageVersion Installed" \ No newline at end of file diff --git a/tests/packages/upgradedowngradesdependency/2.0.0/tools/chocolateyuninstall.ps1 b/tests/packages/upgradedowngradesdependency/2.0.0/tools/chocolateyuninstall.ps1 new file mode 100644 index 0000000000..9ead91ffa3 --- /dev/null +++ b/tests/packages/upgradedowngradesdependency/2.0.0/tools/chocolateyuninstall.ps1 @@ -0,0 +1 @@ +Write-Output "$env:PackageName $env:PackageVersion Uninstalled" \ No newline at end of file diff --git a/tests/packages/upgradedowngradesdependency/2.0.0/upgradedowngradesdependency.nuspec b/tests/packages/upgradedowngradesdependency/2.0.0/upgradedowngradesdependency.nuspec new file mode 100644 index 0000000000..a2728342a2 --- /dev/null +++ b/tests/packages/upgradedowngradesdependency/2.0.0/upgradedowngradesdependency.nuspec @@ -0,0 +1,22 @@ + + + + upgradedowngradesdependency + 2.0.0 + Has out of range Dependency (Below available) + __REPLACE_AUTHORS_OF_SOFTWARE__ + __REPLACE_YOUR_NAME__ + false + __REPLACE__ + Package to test for out of range dependencies. This version uses a dependency that require a lower version. + + + upgradedowngradesdependency admin + + + + + + + + diff --git a/tests/packages/upgradedowngradesdependency/Readme.md b/tests/packages/upgradedowngradesdependency/Readme.md new file mode 100644 index 0000000000..7579fa543b --- /dev/null +++ b/tests/packages/upgradedowngradesdependency/Readme.md @@ -0,0 +1,6 @@ +These packages can be used to test the installation or upgrading of packages that have require an existing package to downgrade. + +Each version is available as `upgradedowngradesdependency` and `downgradesdependency`. This is to allow testing of scenarios where `choco upgrade all` would process the dependency before and after the parent package. + +- Version 1.0.0 Contains a range that can be used in an upgrade scenario and has a dependency on `isdependency 1.0.0 or greater` +- Version 2.0.0 Contains an exact dependency on `isdependency` with a version of `1.0.0` From e5c583836da971fe81a72ba5d913c8ea1d212bde Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Thu, 15 Aug 2024 09:40:15 -0700 Subject: [PATCH 06/14] (#3461,#3487) Add an all packages source for tests We have added some tests for the install all command. This adds a new package source to the testing environment so that we can run the tests locally and in Test Kitchen. --- Invoke-Tests.ps1 | 26 ++++++++++++++++++++++++-- tests/Vagrantfile | 1 + 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Invoke-Tests.ps1 b/Invoke-Tests.ps1 index d6ce96f030..9fe215b795 100644 --- a/Invoke-Tests.ps1 +++ b/Invoke-Tests.ps1 @@ -54,12 +54,33 @@ else { if (-not (Test-Path "$TestPath/packages") -or -not $SkipPackaging) { $null = New-Item -Path "$TestPath/packages" -ItemType Directory -Force # Get and pack packages - $nuspecs = Get-ChildItem -Path $PSScriptRoot/src/chocolatey.tests.integration, $PSScriptRoot/tests/packages -Recurse -Include *.nuspec | Where-Object FullName -notmatch 'bin' + $nuspecs = Get-ChildItem -Path $PSScriptRoot/src/chocolatey.tests.integration, $PSScriptRoot/tests/packages -Recurse -Include *.nuspec | Where-Object FullName -NotMatch 'bin' Get-ChildItem -Path $PSScriptRoot/tests/packages -Recurse -Include *.nupkg | Copy-Item -Destination "$TestPath/packages" foreach ($file in $nuspecs) { Write-Host "Packaging $file" - $null = choco pack $file.FullName --out "$TestPath/packages" + # Include allow-unofficial in case an unofficial Chocolatey has been installed globally for testing + $null = choco pack $file.FullName --out "$TestPath/packages" --allow-unofficial + } +} + +if (-not (Test-Path "$TestPath/all-packages") -or -not $SkipPackaging) { + $null = New-Item -Path "$TestPath/all-packages" -ItemType Directory -Force + + # These are the package ids that are loaded into the all packages test repository. + $AllPackagesRepository = @( + 'isdependency' + 'hasdependency' + 'hasnesteddependency' + 'downgradesdependency' + 'dependencyfailure' + 'hasfailingnesteddependency' + 'failingdependency' + 'isexactversiondependency' + ) + + foreach ($package in $AllPackagesRepository) { + $null = Copy-Item "$TestPath/packages/$package.*.nupkg" "$TestPath/all-packages/" } } @@ -97,6 +118,7 @@ try { Import-Module $PSScriptRoot\tests\helpers\common-helpers.psm1 -Force $null = Invoke-Choco source add --name hermes --source "$TestPath/packages" + $null = Invoke-Choco source add --name hermes-all --source "$TestPath/all-packages" Enable-ChocolateyFeature -Name allowGlobalConfirmation $PesterConfiguration = [PesterConfiguration]@{ Run = @{ diff --git a/tests/Vagrantfile b/tests/Vagrantfile index a6bd2bf065..ceef065bc1 100644 --- a/tests/Vagrantfile +++ b/tests/Vagrantfile @@ -69,6 +69,7 @@ Vagrant.configure("2") do |config| config.vm.provision "shell", name: "clear-packages", inline: <<-SHELL Write-Host "($(Get-Date -Format "dddd MM/dd/yyyy HH:mm:ss K")) Clearing the packages directory" Remove-Item "$env:TEMP/chocolateyTests/packages" -Recurse -Force -ErrorAction SilentlyContinue + Remove-Item "$env:TEMP/chocolateyTests/all-packages" -Recurse -Force -ErrorAction SilentlyContinue SHELL config.vm.provision "shell", name: "test", inline: <<-SHELL # Copy changed files. From d77c0bd519460fb2b10733c6e88a2ec52a19ea83 Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Thu, 15 Aug 2024 09:40:46 -0700 Subject: [PATCH 07/14] (#3461,#3487) Add pester tests for dependencies Add a number of tests for dependency scenarios where we did not have tests before. --- .../Get-ChocolateyInstalledPackages.ps1 | 3 + .../commands/choco-install.Tests.ps1 | 236 ++++++++++++++---- .../commands/choco-upgrade.Tests.ps1 | 96 +++++++ .../commands/failingnested.packages.config | 11 + 4 files changed, 304 insertions(+), 42 deletions(-) create mode 100644 tests/helpers/common/Chocolatey/Get-ChocolateyInstalledPackages.ps1 create mode 100644 tests/pester-tests/commands/failingnested.packages.config diff --git a/tests/helpers/common/Chocolatey/Get-ChocolateyInstalledPackages.ps1 b/tests/helpers/common/Chocolatey/Get-ChocolateyInstalledPackages.ps1 new file mode 100644 index 0000000000..0881ab2bc6 --- /dev/null +++ b/tests/helpers/common/Chocolatey/Get-ChocolateyInstalledPackages.ps1 @@ -0,0 +1,3 @@ +function Get-ChocolateyInstalledPackages { + (Invoke-Choco list -r).Lines | ConvertFrom-ChocolateyOutput -Command List +} diff --git a/tests/pester-tests/commands/choco-install.Tests.ps1 b/tests/pester-tests/commands/choco-install.Tests.ps1 index 3b1c075fa5..719c0e1a5a 100644 --- a/tests/pester-tests/commands/choco-install.Tests.ps1 +++ b/tests/pester-tests/commands/choco-install.Tests.ps1 @@ -1,4 +1,4 @@ -Describe "choco install" -Tag Chocolatey, InstallCommand { +Describe "choco install" -Tag Chocolatey, InstallCommand { BeforeDiscovery { $isLicensed30OrMissingVersion = Test-PackageIsEqualOrHigher 'chocolatey.extension' '3.0.0-beta' -AllowMissingPackage $licensedProxyFixed = Test-PackageIsEqualOrHigher 'chocolatey.extension' 2.2.0-beta -AllowMissingPackage @@ -217,7 +217,8 @@ Describe "choco install" -Tag Chocolatey, InstallCommand { It "Should mention that package hash verification was skipped since local folder source is being used" { if ((Test-HasNuGetV3Source) -or (-not $env:TEST_KITCHEN)) { $Output.Lines | Should -Contain "Source does not provide a package hash, skipping package hash validation." -Because $Output.String - } else { + } + else { $Output.Lines | Should -Contain "Package hash matches expected hash." -Because $Output.String } } @@ -1690,7 +1691,7 @@ To install a local, or remote file, you may use: $PackageUnderTest = "installpackage", "packagewithscript" - $Output = "a`n"*2 | Invoke-Choco install @PackageUnderTest + $Output = "a`n" * 2 | Invoke-Choco install @PackageUnderTest } It "Installs successfully and exits with success (0)" { @@ -1740,7 +1741,8 @@ To install a local, or remote file, you may use: It 'Outputs download completed' { $testMessage = if ($features.License) { "Download of 'cmake-3.21.2-windows-x86_64.zip' (36.01 MB) completed." - } else { + } + else { "Download of cmake-3.21.2-windows-x86_64.zip (36.01 MB) completed." } $Output.Lines | Should -Contain $testMessage -Because $Output.String @@ -1749,7 +1751,8 @@ To install a local, or remote file, you may use: It 'Outputs extracting correct archive' { $testMessage = if ($features.License) { "Extracting cmake-3.21.2-windows-x86_64.zip to $env:ChocolateyInstall\lib\install-chocolateyzip\tools..." - } else { + } + else { "Extracting $($paths.CachePathLong)\install-chocolateyzip\3.21.2\cmake-3.21.2-windows-x86_64.zip to $env:ChocolateyInstall\lib\install-chocolateyzip\tools..." } $Output.Lines | Should -Contain $testMessage -Because $Output.String @@ -1925,8 +1928,8 @@ To install a local, or remote file, you may use: } Context "Installing a package with a non-normalized version number" -ForEach @( - @{ ExpectedPackageVersion = '1.0.0' ; SearchVersion = '1' ; NuspecVersion = '01.0.0.0'} - @{ ExpectedPackageVersion = '1.0.0' ; SearchVersion = '1.0' ; NuspecVersion = '01.0.0.0'} + @{ ExpectedPackageVersion = '1.0.0' ; SearchVersion = '1' ; NuspecVersion = '01.0.0.0' } + @{ ExpectedPackageVersion = '1.0.0' ; SearchVersion = '1.0' ; NuspecVersion = '01.0.0.0' } @{ ExpectedPackageVersion = '1.0.0' ; SearchVersion = '1.0.0' ; NuspecVersion = '01.0.0.0' } @{ ExpectedPackageVersion = '4.0.1' ; SearchVersion = '4.0.1' ; NuspecVersion = '004.0.01.0' } @{ ExpectedPackageVersion = '1.0.0' ; SearchVersion = '01.0.0.0' ; NuspecVersion = '01.0.0.0' } @@ -2027,21 +2030,21 @@ To install a local, or remote file, you may use: } It 'Outputs as ' -ForEach @(@{ - Name = 'chocolateyPackageVersion' - Value= '0.9.0' - } - @{ - Name = 'packageVersion' - Value= '0.9.0' - } - @{ - Name = 'chocolateyPackageNuspecVersion' - Value= '0.9' - } - @{ - Name = 'packageNuspecVersion' - Value= '0.9' - }) { + Name = 'chocolateyPackageVersion' + Value = '0.9.0' + } + @{ + Name = 'packageVersion' + Value = '0.9.0' + } + @{ + Name = 'chocolateyPackageNuspecVersion' + Value = '0.9' + } + @{ + Name = 'packageNuspecVersion' + Value = '0.9' + }) { $Output.Lines | Should -Contain "$Name=$Value" } } @@ -2070,51 +2073,200 @@ To install a local, or remote file, you may use: } } - Context 'Installing a package should not downgrade an existing package dependency.' -Tag Downgrade { + Context 'Installing a package with argument () should () downgrade an existing package dependency.' -Tag Downgrade -ForEach @( + @{ + Argument = '--force' + AllowsDowngrade = $true + ExpectedExit = 0 + } + @{ + Argument = '--allow-downgrade' + AllowsDowngrade = $true + ExpectedExit = 0 + } + @{ + Argument = '' + AllowsDowngrade = $false + ExpectedExit = 1 + } + ) { BeforeAll { $DependentPackage = @{ - Name = 'isexactversiondependency' - Version = '2.0.0' + Name = 'isdependency' + Version = '2.1.0' } Restore-ChocolateyInstallSnapshot $Setup = Invoke-Choco install $DependentPackage.Name --version $DependentPackage.Version --confirm - $Output = Invoke-Choco install toplevelhasexactversiondependency + $Output = Invoke-Choco install downgradesdependency --confirm $Argument + $Packages = Get-ChocolateyInstalledPackages } - It "Exits with Failure (1)" { - $Output.ExitCode | Should -Be 1 -Because $Output.String + It "Exits correctly ()" { + $Output.ExitCode | Should -Be $ExpectedExit -Because $Output.String + } + + It "Reports that it can () downgrade isdependency" { + if ($AllowsDowngrade) { + $Output.Lines | Should -Contain 'Chocolatey installed 2/2 packages.' -Because $Output.String + } + else { + $Output.Lines | Should -Contain 'Chocolatey installed 0/2 packages. 2 packages failed.' -Because $Output.String + } + + $Output.Lines | Should -Contain -Not:($AllowsDowngrade) "A newer version of $($DependentPackage.Name) (v$($DependentPackage.Version)) is already installed." -Because $Output.String + $Output.Lines | Should -Contain -Not:($AllowsDowngrade) 'Use --allow-downgrade or --force to attempt to install older versions.' -Because $Output.String } - It "Reports that it cannot downgrade isexactversiondependency" { - $Output.Lines | Should -Contain 'A newer version of isexactversiondependency (v2.0.0) is already installed.' -Because $Output.String - $Output.Lines | Should -Contain 'Use --allow-downgrade or --force to attempt to install older versions.' -Because $Output.String - $Output.Lines | Should -Contain 'Chocolatey installed 0/3 packages. 3 packages failed.' -Because $Output.String + It "Should have the expected packages" { + if ($AllowsDowngrade) { + $Packages | where { $_.Name -eq $DependentPackage.Name -and $_.Version -eq '1.0.0' } | Should -Not -BeNullOrEmpty -Because "Packages: $Packages $($Output.String)" + } + else { + $Packages | where { $_.Name -eq $DependentPackage.Name -and $_.Version -eq $DependentPackage.Version } | Should -Not -BeNullOrEmpty -Because "Packages: $Packages $($Output.String)" + } } } - Context 'Installing a package should downgrade an existing package dependency when <_> is used.' -ForEach @('--force', '--allow-downgrade') -Tag Downgrade { + Context 'Installing a package with argument () should () downgrade an existing package dependency.' -Tag Downgrade, StopOnFirstPackageFailure -ForEach @( + @{ + Argument = '--force' + AllowsDowngrade = $true + ExpectedExit = 0 + } + @{ + Argument = '--allow-downgrade' + AllowsDowngrade = $true + ExpectedExit = 0 + } + @{ + Argument = '' + AllowsDowngrade = $false + ExpectedExit = 1 + } + ) { BeforeAll { $DependentPackage = @{ - Name = 'isexactversiondependency' - Version = '2.0.0' + Name = 'isdependency' + Version = '2.1.0' } Restore-ChocolateyInstallSnapshot $Setup = Invoke-Choco install $DependentPackage.Name --version $DependentPackage.Version --confirm - $Output = Invoke-Choco install toplevelhasexactversiondependency $_ + $null = Enable-ChocolateyFeature -Name StopOnFirstPackageFailure + $Output = Invoke-Choco install downgradesdependency installpackage --confirm $Argument + $Packages = Get-ChocolateyInstalledPackages } - It "Exits with Success (0)" { - $Output.ExitCode | Should -Be 0 -Because $Output.String + It "Exits correctly ()" { + $Output.ExitCode | Should -Be $ExpectedExit -Because $Output.String + } + + It "Reports that it can () downgrade isdependency" { + $Output.Lines | Should -Contain -Not:($AllowsDowngrade) "A newer version of $($DependentPackage.Name) (v$($DependentPackage.Version)) is already installed." -Because $Output.String + $Output.Lines | Should -Contain -Not:($AllowsDowngrade) 'Use --allow-downgrade or --force to attempt to install older versions.' -Because $Output.String + } + + It "Should have the expected packages" { + if ($AllowsDowngrade) { + $Packages | where { $_.Name -eq $DependentPackage.Name -and $_.Version -eq '1.0.0' } | Should -Not -BeNullOrEmpty -Because "Packages: $Packages $($Output.String)" + } + else { + $Packages | where { $_.Name -eq $DependentPackage.Name -and $_.Version -eq $DependentPackage.Version } | Should -Not -BeNullOrEmpty -Because "Packages: $Packages $($Output.String)" + } + } + } + + Context 'Installing a package () with a failing nested dependency should not install the package with failing dependencies' -ForEach @( + @{ + PackageName = 'dependencyfailure;downgradesdependency;failingdependency;hasdependency;hasfailingnesteddependency;hasnesteddependency;isdependency;isexactversiondependency'.Split(';') + } + @{ + PackageName = @('packages.config') + } + @{ + PackageName = @('all') + } + ) { + BeforeAll { + + Restore-ChocolateyInstallSnapshot -SetWorkingDirectory + + Copy-Item "$PSScriptRoot/failingnested.packages.config" './packages.config' + Disable-ChocolateySource -All + Enable-ChocolateySource -Name 'hermes-all' + + $Output = Invoke-Choco install @PackageName --confirm + $Packages = Get-ChocolateyInstalledPackages + } + + It "Exits correctly (15608)" { + # failingdependency exits with 15608, so Chocolatey exits with that. + $Output.ExitCode | Should -Be 15608 -Because $Output.String + } + + It "Should have the expected packages" { + $ExpectedPackages = @( + "downgradesdependency" + "isdependency" + "isexactversiondependency" + ) + $UnexpectedPackages = @( + 'dependencyfailure' + "dependencyfailure" + 'hasfailingnesteddependency' + ) + + foreach ($package in $ExpectedPackages) { + $Packages.Name | Should -Contain $package -Because "Package: $package $($Output.String)" + } + + foreach ($package in $UnexpectedPackages) { + $Packages.Name | Should -Not -Contain $package -Because "Package: $package $($Output.String)" + } } + } + + Context 'Installing a package () with a failing nested dependency should not install the package with failing dependencies' -ForEach @( @{ PackageName = 'hasfailingnesteddependency;hasnesteddependency' } ) { + BeforeAll { + + Restore-ChocolateyInstallSnapshot -SetWorkingDirectory + + Disable-ChocolateySource -All + Enable-ChocolateySource -Name 'hermes-all' - It "Does not report that it cannot downgrade isexactversiondependency" { - $Output.Lines | Should -Not -Contain 'A newer version of isexactversiondependency (v2.0.0) is already installed.' -Because $Output.String - $Output.Lines | Should -Not -Contain 'Use --allow-downgrade or --force to attempt to install older versions.' -Because $Output.String - $Output.Lines | Should -Contain 'Chocolatey installed 3/3 packages.' -Because $Output.String + $Output = Invoke-Choco install $PackageName --confirm + $Packages = Get-ChocolateyInstalledPackages + } + + It "Exits correctly (15608)" { + # failingdependency exits with 15608, so Chocolatey exits with that. + $Output.ExitCode | Should -Be 15608 -Because $Output.String + } + + It "Should have the expected packages" { + $ExpectedPackages = @( + "downgradesdependency" + "hasnesteddependency" + "isdependency" + "hasdependency" + ) + $UnexpectedPackages = @( + "dependencyfailure" + "isexactversiondependency" + 'dependencyfailure' + 'hasfailingnesteddependency' + ) + + foreach ($package in $ExpectedPackages) { + $Packages.Name | Should -Contain $package -Because "Package: $package $($Output.String)" + } + + foreach ($package in $UnexpectedPackages) { + $Packages.Name | Should -Not -Contain $package -Because "Package: $package $($Output.String)" + } } } diff --git a/tests/pester-tests/commands/choco-upgrade.Tests.ps1 b/tests/pester-tests/commands/choco-upgrade.Tests.ps1 index 460b72ec64..0eb1329ba4 100644 --- a/tests/pester-tests/commands/choco-upgrade.Tests.ps1 +++ b/tests/pester-tests/commands/choco-upgrade.Tests.ps1 @@ -736,6 +736,102 @@ To upgrade a local, or remote file, you may use: } } + Context 'Upgrading a package () with should downgrade () an existing package dependency.' -Tag Downgrade -ForEach @( + @{ + Argument = '--force' + AllowsDowngrade = $true + ExpectedExit = 0 + PackageName = 'upgradedowngradesdependency' + BasePackage = 'upgradedowngradesdependency' + } + @{ + Argument = '--allow-downgrade' + AllowsDowngrade = $true + ExpectedExit = 0 + PackageName = 'upgradedowngradesdependency' + BasePackage = 'upgradedowngradesdependency' + } + @{ + Argument = '' + AllowsDowngrade = $false + ExpectedExit = 1 + PackageName = 'upgradedowngradesdependency' + BasePackage = 'upgradedowngradesdependency' + } + @{ + Argument = '--force' + AllowsDowngrade = $true + ExpectedExit = 0 + PackageName = 'all' + BasePackage = 'upgradedowngradesdependency' + } + @{ + Argument = '--allow-downgrade' + AllowsDowngrade = $true + ExpectedExit = 0 + PackageName = 'all' + BasePackage = 'upgradedowngradesdependency' + } + @{ + Argument = '' + AllowsDowngrade = $false + ExpectedExit = 1 + PackageName = 'all' + BasePackage = 'upgradedowngradesdependency' + } + @{ + Argument = '--force' + AllowsDowngrade = $true + ExpectedExit = 0 + PackageName = 'all' + BasePackage = 'downgradesdependency' + } + @{ + Argument = '--allow-downgrade' + AllowsDowngrade = $true + ExpectedExit = 0 + PackageName = 'all' + BasePackage = 'downgradesdependency' + } + @{ + Argument = '' + AllowsDowngrade = $false + ExpectedExit = 1 + PackageName = 'all' + BasePackage = 'downgradesdependency' + } + ) { + BeforeAll { + $DependentPackage = @{ + Name = 'isdependency' + Version = '2.1.0' + } + + Restore-ChocolateyInstallSnapshot + + $Setup = Invoke-Choco install $DependentPackage.Name --version $DependentPackage.Version --confirm + $Setup2 = Invoke-Choco install $BasePackage --version 1.0.0 --confirm + $Output = Invoke-Choco upgrade $PackageName --confirm --except="'chocolatey'" $Argument + } + + It "Exits with expected result ()" { + $Output.ExitCode | Should -Be $ExpectedExit -Because $Output.String + } + + It "Reports correctly about downgrading isdependency" { + if ($AllowsDowngrade) { + $Output.Lines | Should -Not -Contain 'A newer version of isdependency (v2.1.0) is already installed.' -Because $Output.String + $Output.Lines | Should -Not -Contain 'Use --allow-downgrade or --force to attempt to install older versions.' -Because $Output.String + $Output.String | Should -MatchExactly 'Chocolatey upgraded 2/\d+ packages.' + } + else { + $Output.Lines | Should -Contain 'A newer version of isdependency (v2.1.0) is already installed.' -Because $Output.String + $Output.Lines | Should -Contain 'Use --allow-downgrade or --force to attempt to install older versions.' -Because $Output.String + $Output.String | Should -MatchExactly 'Chocolatey upgraded 0/\d+ packages. 2 packages failed.' + } + } + } + # This needs to be (almost) the last test in this block, to ensure NuGet configurations aren't being created. # Any tests after this block are expected to generate the configuration as they're explicitly using the NuGet CLI Test-NuGetPaths diff --git a/tests/pester-tests/commands/failingnested.packages.config b/tests/pester-tests/commands/failingnested.packages.config new file mode 100644 index 0000000000..698f931c4f --- /dev/null +++ b/tests/pester-tests/commands/failingnested.packages.config @@ -0,0 +1,11 @@ + + + + + + + + + + + From 53264d2b39e64dd4ac0e72a11c124839d96fc25e Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Mon, 26 Aug 2024 09:54:49 -0700 Subject: [PATCH 08/14] (maint) Remove unnecessary variable usage In the NugetService we were using a nullResult variable to allow us to add messages to the result. We do not need this variable if we're only adding a single message. This commit removes the unnecessary variables. --- .../services/NugetService.cs | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index 03ed7e4fb6..634cfe2d88 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -605,6 +605,7 @@ public virtual ConcurrentDictionary Install(ChocolateyCon if (installedPackage != null && (version == null || version == installedPackage.PackageMetadata.Version) && !config.Force) { var logMessage = "{0} v{1} already installed.{2} Use --force to reinstall, specify a version to install, or try upgrade.".FormatWith(installedPackage.Name, installedPackage.Version, Environment.NewLine); + // We need a temporary PackageResult so that we can add to the Messages collection. var nullResult = packageResultsToReturn.GetOrAdd(packageName, installedPackage); nullResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage)); nullResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage)); @@ -626,8 +627,8 @@ public virtual ConcurrentDictionary Install(ChocolateyCon if (installedPackage != null && version != null && version < installedPackage.PackageMetadata.Version && !config.AllowDowngrade) { var logMessage = StringResources.ErrorMessages.UnableToDowngrade.FormatWith(installedPackage.Name, installedPackage.Version, Environment.NewLine); - var nullResult = packageResultsToReturn.GetOrAdd(packageName, installedPackage); - nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); + packageResultsToReturn.GetOrAdd(packageName, installedPackage) + .Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); continue; } @@ -803,9 +804,12 @@ Version was specified as '{0}'. It is possible that version if (packageDependencyInfo != null && packageResultsToReturn.Any(r => r.Value.Success != true && packageDependencyInfo.Dependencies.Any(d => d.Id == r.Value.Identity.Id))) { var logMessage = StringResources.ErrorMessages.DependencyFailedToInstall.FormatWith(packageDependencyInfo.Id); - var x = new PackageResult(packageDependencyInfo.Id, packageDependencyInfo.Version.ToStringSafe(), string.Empty); - var nullResult = packageResultsToReturn.GetOrAdd(packageDependencyInfo.Id, x); - nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); + packageResultsToReturn + .GetOrAdd( + packageDependencyInfo.Id, + new PackageResult(packageDependencyInfo.Id, packageDependencyInfo.Version.ToStringSafe(), string.Empty) + ) + .Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); if (config.Features.StopOnFirstPackageFailure) @@ -836,8 +840,8 @@ Version was specified as '{0}'. It is possible that version if (!config.AllowDowngrade && packageToUninstall.Identity.HasVersion && packageDependencyInfo.HasVersion && packageDependencyInfo.Version < packageToUninstall.Identity.Version) { var logMessage = StringResources.ErrorMessages.UnableToDowngrade.FormatWith(packageToUninstall.Name, packageToUninstall.Version, Environment.NewLine); - var nullResult = packageResultsToReturn.GetOrAdd(packageToUninstall.Name, packageToUninstall); - nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); + packageResultsToReturn.GetOrAdd(packageToUninstall.Name, packageToUninstall) + .Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); if (config.Features.StopOnFirstPackageFailure) @@ -1184,8 +1188,8 @@ public virtual ConcurrentDictionary Upgrade(ChocolateyCon if (version != null && version < installedPackage.PackageMetadata.Version && !config.AllowDowngrade) { var logMessage = StringResources.ErrorMessages.UnableToDowngrade.FormatWith(installedPackage.PackageMetadata.Id, installedPackage.Version, Environment.NewLine); - var nullResult = packageResultsToReturn.GetOrAdd(packageName, new PackageResult(installedPackage.PackageMetadata, pathResolver.GetInstallPath(installedPackage.PackageMetadata.Id))); - nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); + packageResultsToReturn.GetOrAdd(packageName, new PackageResult(installedPackage.PackageMetadata, pathResolver.GetInstallPath(installedPackage.PackageMetadata.Id))) + .Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); continue; } @@ -1608,9 +1612,11 @@ public virtual ConcurrentDictionary Upgrade(ChocolateyCon if (packageResultsToReturn.Any(r => r.Value.Success != true && packageDependencyInfo.Dependencies.Any(d => d.Id == r.Value.Identity.Id))) { var logMessage = StringResources.ErrorMessages.DependencyFailedToInstall.FormatWith(packageDependencyInfo.Id, packageDependencyInfo.Version); - var x = new PackageResult(packageDependencyInfo.Id, packageDependencyInfo.Version.ToStringSafe(), string.Empty); - var nullResult = packageResultsToReturn.GetOrAdd(packageDependencyInfo.Id, x); - nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); + packageResultsToReturn.GetOrAdd( + packageDependencyInfo.Id, + new PackageResult(packageDependencyInfo.Id, packageDependencyInfo.Version.ToStringSafe(), string.Empty) + ) + .Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); if (config.Features.StopOnFirstPackageFailure) @@ -1642,8 +1648,8 @@ public virtual ConcurrentDictionary Upgrade(ChocolateyCon if (!config.AllowDowngrade && packageToUninstall.Identity.HasVersion && packageDependencyInfo.HasVersion && packageDependencyInfo.Version < packageToUninstall.Identity.Version) { var logMessage = StringResources.ErrorMessages.UnableToDowngrade.FormatWith(packageToUninstall.Name, packageToUninstall.Version, Environment.NewLine); - var nullResult = packageResultsToReturn.GetOrAdd(packageToUninstall.Name, packageToUninstall); - nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); + packageResultsToReturn.GetOrAdd(packageToUninstall.Name, packageToUninstall) + .Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); if (config.Features.StopOnFirstPackageFailure) @@ -1655,7 +1661,7 @@ public virtual ConcurrentDictionary Upgrade(ChocolateyCon } // Package was previously marked inconclusive (not upgraded). We need remove the message since we are now upgrading it. - // Packages that are inconclusive but successfull are not labeled as successful at the end of the run. + // Packages that are inconclusive but successful are not labeled as successful at the end of the run. var checkResult = packageResultsToReturn.GetOrAdd(packageToUninstall.Name, packageToUninstall); while (checkResult.Inconclusive) From acdf0ba59a546a291e77a4142e701c5806d0a048 Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Fri, 30 Aug 2024 15:14:03 -0700 Subject: [PATCH 09/14] fixup! (#3461,#3487) Add pester tests for dependencies --- tests/pester-tests/commands/choco-install.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pester-tests/commands/choco-install.Tests.ps1 b/tests/pester-tests/commands/choco-install.Tests.ps1 index 719c0e1a5a..cbac68a900 100644 --- a/tests/pester-tests/commands/choco-install.Tests.ps1 +++ b/tests/pester-tests/commands/choco-install.Tests.ps1 @@ -2129,7 +2129,7 @@ To install a local, or remote file, you may use: } } - Context 'Installing a package with argument () should () downgrade an existing package dependency.' -Tag Downgrade, StopOnFirstPackageFailure -ForEach @( + Context 'Installing a package with argument () and StopOnFirstPackageFailure enabled should () downgrade an existing package dependency and correctly handle installpackage.' -Tag Downgrade, StopOnFirstPackageFailure -ForEach @( @{ Argument = '--force' AllowsDowngrade = $true From dc713f1d9177a936f283d28e1c630bc2847536e8 Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Fri, 30 Aug 2024 15:14:33 -0700 Subject: [PATCH 10/14] fixup! (#3461,#3487) Add test packages for added tests --- .../packages/dependencyfailure/dependencyfailure.nuspec | 8 ++++++-- .../packages/failingdependency/failingdependency.nuspec | 4 ++-- .../failingdependency/tools/chocolateyinstall.ps1 | 1 - .../1.0.0/hasfailingnesteddependency.nuspec | 8 ++++++-- .../1.0.0/downgradesdependency.nuspec | 9 ++++++++- .../1.0.0/upgradedowngradesdependency.nuspec | 9 ++++++++- .../2.0.0/downgradesdependency.nuspec | 9 ++++++++- .../2.0.0/upgradedowngradesdependency.nuspec | 9 ++++++++- tests/packages/upgradedowngradesdependency/Readme.md | 6 +++--- 9 files changed, 49 insertions(+), 14 deletions(-) diff --git a/tests/packages/dependencyfailure/dependencyfailure.nuspec b/tests/packages/dependencyfailure/dependencyfailure.nuspec index 46f577f772..4ab6e842ad 100644 --- a/tests/packages/dependencyfailure/dependencyfailure.nuspec +++ b/tests/packages/dependencyfailure/dependencyfailure.nuspec @@ -7,8 +7,12 @@ __REPLACE_AUTHORS_OF_SOFTWARE_COMMA_SEPARATED__ https://_Software_Location_REMOVE_OR_FILL_OUT_ dependencyfailure admin SPACE_SEPARATED - __REPLACE__ - __REPLACE__MarkDown_Okay + Package includes a dependency for a package that is known to fail installation. + + Package includes a dependency for a package that is known to fail installation. + + It can be used in tests to ensure that failing dependencies do not allow the package to install. + diff --git a/tests/packages/failingdependency/failingdependency.nuspec b/tests/packages/failingdependency/failingdependency.nuspec index 66769fd42c..c8179b5e80 100644 --- a/tests/packages/failingdependency/failingdependency.nuspec +++ b/tests/packages/failingdependency/failingdependency.nuspec @@ -7,8 +7,8 @@ __REPLACE_AUTHORS_OF_SOFTWARE_COMMA_SEPARATED__ https://_Software_Location_REMOVE_OR_FILL_OUT_ dependencyfailure admin SPACE_SEPARATED - __REPLACE__ - __REPLACE__MarkDown_Okay + Package that fails to install. Used as part of dependency tree. + Package that fails to install. Used as part of dependency tree. diff --git a/tests/packages/failingdependency/tools/chocolateyinstall.ps1 b/tests/packages/failingdependency/tools/chocolateyinstall.ps1 index b14a38a512..04105d6173 100644 --- a/tests/packages/failingdependency/tools/chocolateyinstall.ps1 +++ b/tests/packages/failingdependency/tools/chocolateyinstall.ps1 @@ -1,3 +1,2 @@ Write-Error "This should fail!" $env:ChocolateyExitCode = '15608' -#throw "This is crap" \ No newline at end of file diff --git a/tests/packages/hasfailingnesteddependency/1.0.0/hasfailingnesteddependency.nuspec b/tests/packages/hasfailingnesteddependency/1.0.0/hasfailingnesteddependency.nuspec index 3113e456a8..0479bb03ec 100644 --- a/tests/packages/hasfailingnesteddependency/1.0.0/hasfailingnesteddependency.nuspec +++ b/tests/packages/hasfailingnesteddependency/1.0.0/hasfailingnesteddependency.nuspec @@ -7,8 +7,12 @@ __REPLACE_AUTHORS_OF_SOFTWARE__ __REPLACE_YOUR_NAME__ false - __REPLACE__ - __REPLACE__ + + Package that contains dependencies that have dependencies that may fail to install. + + Used for testing dependency resolution and ensuring dependency failures do not allow package installation. + + Package that contains dependencies that have dependencies that may fail to install. hasfailingnesteddependency admin diff --git a/tests/packages/upgradedowngradesdependency/1.0.0/downgradesdependency.nuspec b/tests/packages/upgradedowngradesdependency/1.0.0/downgradesdependency.nuspec index dc187b1bec..142b308132 100644 --- a/tests/packages/upgradedowngradesdependency/1.0.0/downgradesdependency.nuspec +++ b/tests/packages/upgradedowngradesdependency/1.0.0/downgradesdependency.nuspec @@ -7,7 +7,14 @@ __REPLACE_AUTHORS_OF_SOFTWARE__ __REPLACE_YOUR_NAME__ false - __REPLACE__ + + These packages can be used to test the installation or upgrading of packages that require an existing package to downgrade. + +Each version is available as `upgradedowngradesdependency` and `downgradesdependency`. This is to allow testing of scenarios where `choco upgrade all` would process the dependency before and after the parent package. + +- Version 1.0.0 contains a range that can be used in an upgrade scenario and has a dependency on `isdependency 1.0.0 or greater` +- Version 2.0.0 contains an exact dependency on `isdependency` with a version of `1.0.0` + Package to test for out of range dependencies. This 1st version have a valid exact range. diff --git a/tests/packages/upgradedowngradesdependency/1.0.0/upgradedowngradesdependency.nuspec b/tests/packages/upgradedowngradesdependency/1.0.0/upgradedowngradesdependency.nuspec index 829afd16f8..a18dfdf619 100644 --- a/tests/packages/upgradedowngradesdependency/1.0.0/upgradedowngradesdependency.nuspec +++ b/tests/packages/upgradedowngradesdependency/1.0.0/upgradedowngradesdependency.nuspec @@ -7,7 +7,14 @@ __REPLACE_AUTHORS_OF_SOFTWARE__ __REPLACE_YOUR_NAME__ false - __REPLACE__ + + These packages can be used to test the installation or upgrading of packages that require an existing package to downgrade. + +Each version is available as `upgradedowngradesdependency` and `downgradesdependency`. This is to allow testing of scenarios where `choco upgrade all` would process the dependency before and after the parent package. + +- Version 1.0.0 contains a range that can be used in an upgrade scenario and has a dependency on `isdependency 1.0.0 or greater` +- Version 2.0.0 contains an exact dependency on `isdependency` with a version of `1.0.0` + Package to test for out of range dependencies. This 1st version have a valid exact range. diff --git a/tests/packages/upgradedowngradesdependency/2.0.0/downgradesdependency.nuspec b/tests/packages/upgradedowngradesdependency/2.0.0/downgradesdependency.nuspec index 817853880f..42229dc482 100644 --- a/tests/packages/upgradedowngradesdependency/2.0.0/downgradesdependency.nuspec +++ b/tests/packages/upgradedowngradesdependency/2.0.0/downgradesdependency.nuspec @@ -7,7 +7,14 @@ __REPLACE_AUTHORS_OF_SOFTWARE__ __REPLACE_YOUR_NAME__ false - __REPLACE__ + + These packages can be used to test the installation or upgrading of packages that require an existing package to downgrade. + +Each version is available as `upgradedowngradesdependency` and `downgradesdependency`. This is to allow testing of scenarios where `choco upgrade all` would process the dependency before and after the parent package. + +- Version 1.0.0 contains a range that can be used in an upgrade scenario and has a dependency on `isdependency 1.0.0 or greater` +- Version 2.0.0 contains an exact dependency on `isdependency` with a version of `1.0.0` + Package to test for out of range dependencies. This version uses a dependency that require a lower version. diff --git a/tests/packages/upgradedowngradesdependency/2.0.0/upgradedowngradesdependency.nuspec b/tests/packages/upgradedowngradesdependency/2.0.0/upgradedowngradesdependency.nuspec index a2728342a2..58b125b3e7 100644 --- a/tests/packages/upgradedowngradesdependency/2.0.0/upgradedowngradesdependency.nuspec +++ b/tests/packages/upgradedowngradesdependency/2.0.0/upgradedowngradesdependency.nuspec @@ -7,7 +7,14 @@ __REPLACE_AUTHORS_OF_SOFTWARE__ __REPLACE_YOUR_NAME__ false - __REPLACE__ + + These packages can be used to test the installation or upgrading of packages that require an existing package to downgrade. + +Each version is available as `upgradedowngradesdependency` and `downgradesdependency`. This is to allow testing of scenarios where `choco upgrade all` would process the dependency before and after the parent package. + +- Version 1.0.0 contains a range that can be used in an upgrade scenario and has a dependency on `isdependency 1.0.0 or greater` +- Version 2.0.0 contains an exact dependency on `isdependency` with a version of `1.0.0` + Package to test for out of range dependencies. This version uses a dependency that require a lower version. diff --git a/tests/packages/upgradedowngradesdependency/Readme.md b/tests/packages/upgradedowngradesdependency/Readme.md index 7579fa543b..0f2c4f806f 100644 --- a/tests/packages/upgradedowngradesdependency/Readme.md +++ b/tests/packages/upgradedowngradesdependency/Readme.md @@ -1,6 +1,6 @@ -These packages can be used to test the installation or upgrading of packages that have require an existing package to downgrade. +These packages can be used to test the installation or upgrading of packages that require an existing package to downgrade. Each version is available as `upgradedowngradesdependency` and `downgradesdependency`. This is to allow testing of scenarios where `choco upgrade all` would process the dependency before and after the parent package. -- Version 1.0.0 Contains a range that can be used in an upgrade scenario and has a dependency on `isdependency 1.0.0 or greater` -- Version 2.0.0 Contains an exact dependency on `isdependency` with a version of `1.0.0` +- Version 1.0.0 contains a range that can be used in an upgrade scenario and has a dependency on `isdependency 1.0.0 or greater` +- Version 2.0.0 contains an exact dependency on `isdependency` with a version of `1.0.0` From 1becaa76eea327a6cb5b9a0ac3f8821ed0971f6f Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Fri, 30 Aug 2024 15:08:04 -0700 Subject: [PATCH 11/14] (tests) Update Test Package to have description This updates the `test-chocolateypath` package to have a description and removes the unneeded comments. This is related to a GitLab MR that noted these things when bringing this package into the internal repository. This reverts commit ffd9aab4b40dc8b47b84de5f3ce91ea22fda7a6d. --- .../test-chocolateypath.nuspec | 68 +------------------ 1 file changed, 2 insertions(+), 66 deletions(-) diff --git a/tests/packages/test-chocolateypath/test-chocolateypath.nuspec b/tests/packages/test-chocolateypath/test-chocolateypath.nuspec index 9756ecb9c7..580a48463b 100644 --- a/tests/packages/test-chocolateypath/test-chocolateypath.nuspec +++ b/tests/packages/test-chocolateypath/test-chocolateypath.nuspec @@ -1,81 +1,17 @@ - - - - - - - - - - - - - - test-chocolateypath - - - 0.1.0 - - - - - - - test-packagepath (Install) __REPLACE_AUTHORS_OF_SOFTWARE_COMMA_SEPARATED__ - https://_Software_Location_REMOVE_OR_FILL_OUT_ - - - - - - - - - - test-packagepath SPACE_SEPARATED - __REPLACE__ - __REPLACE__MarkDown_Okay - - - - - - - - - - + Package to test the Get-ChocolateyPath Chocolatey PowerShell function. + Package to test the Get-ChocolateyPath Chocolatey PowerShell function. - From a93c0c4007d311d1e6453f8e412340fd7265a362 Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Fri, 20 Sep 2024 16:09:55 -0700 Subject: [PATCH 12/14] (#3461,#3487) Address review comments Address review comments by using full version string for PackageResults, and use case insensitive compares when determining if a package has dependencies that failed to install. --- .../infrastructure.app/services/NugetService.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index 634cfe2d88..c701feb980 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -801,13 +801,13 @@ Version was specified as '{0}'. It is possible that version foreach (SourcePackageDependencyInfo packageDependencyInfo in resolvedPackages) { // Don't attempt to action this package if dependencies failed. - if (packageDependencyInfo != null && packageResultsToReturn.Any(r => r.Value.Success != true && packageDependencyInfo.Dependencies.Any(d => d.Id == r.Value.Identity.Id))) + if (packageDependencyInfo != null && packageResultsToReturn.Any(r => r.Value.Success != true && packageDependencyInfo.Dependencies.Any(d => d.Id.Equals(r.Value.Identity.Id, StringComparison.OrdinalIgnoreCase)))) { var logMessage = StringResources.ErrorMessages.DependencyFailedToInstall.FormatWith(packageDependencyInfo.Id); packageResultsToReturn .GetOrAdd( packageDependencyInfo.Id, - new PackageResult(packageDependencyInfo.Id, packageDependencyInfo.Version.ToStringSafe(), string.Empty) + new PackageResult(packageDependencyInfo.Id, packageDependencyInfo.Version.ToFullStringChecked(), string.Empty) ) .Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); @@ -1609,12 +1609,12 @@ public virtual ConcurrentDictionary Upgrade(ChocolateyCon } // Don't attempt to action this package if dependencies failed. - if (packageResultsToReturn.Any(r => r.Value.Success != true && packageDependencyInfo.Dependencies.Any(d => d.Id == r.Value.Identity.Id))) + if (packageResultsToReturn.Any(r => r.Value.Success != true && packageDependencyInfo.Dependencies.Any(d => d.Id.Equals(r.Value.Identity.Id, StringComparison.OrdinalIgnoreCase)))) { var logMessage = StringResources.ErrorMessages.DependencyFailedToInstall.FormatWith(packageDependencyInfo.Id, packageDependencyInfo.Version); packageResultsToReturn.GetOrAdd( packageDependencyInfo.Id, - new PackageResult(packageDependencyInfo.Id, packageDependencyInfo.Version.ToStringSafe(), string.Empty) + new PackageResult(packageDependencyInfo.Id, packageDependencyInfo.Version.ToFullStringChecked(), string.Empty) ) .Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); From 930f39403aca957276b5331edd04e5193c8b24aa Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Fri, 20 Sep 2024 16:08:35 -0700 Subject: [PATCH 13/14] (maint) Output choco pack failures This adds logic to the Invoke-Tests file to output if a package failed fail to pack. This allows for improved developer experience by indicating if packages fail to build. This also allows impromptu improvement to the developer experience by allowing simple changes to the script to throw in place of outputting an errorand thus not allowing tests to run without the full set of test packages. --- Invoke-Tests.ps1 | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/Invoke-Tests.ps1 b/Invoke-Tests.ps1 index 9fe215b795..6ff80f79bc 100644 --- a/Invoke-Tests.ps1 +++ b/Invoke-Tests.ps1 @@ -57,10 +57,30 @@ if (-not (Test-Path "$TestPath/packages") -or -not $SkipPackaging) { $nuspecs = Get-ChildItem -Path $PSScriptRoot/src/chocolatey.tests.integration, $PSScriptRoot/tests/packages -Recurse -Include *.nuspec | Where-Object FullName -NotMatch 'bin' Get-ChildItem -Path $PSScriptRoot/tests/packages -Recurse -Include *.nupkg | Copy-Item -Destination "$TestPath/packages" - foreach ($file in $nuspecs) { - Write-Host "Packaging $file" + $packFailures = foreach ($file in $nuspecs) { # Include allow-unofficial in case an unofficial Chocolatey has been installed globally for testing - $null = choco pack $file.FullName --out "$TestPath/packages" --allow-unofficial + $packOutput = choco pack $file.FullName --out "$TestPath/packages" --allow-unofficial + if ($LASTEXITCODE -ne 0) { + [pscustomobject]@{ + Package = $file.FullName + ExitCode = $LASTEXITCODE + Output = $packOutput + } + Write-Warning "Failed to pack $file" + } + else { + Write-Host "Packaged $file" + } + } + + if ($null -ne $packFailures) { + foreach ($failure in $packFailures) { + Write-Warning "$($failure.Package) failed to pack with exit code: $($failure.ExitCode)" + $failure.Output | Write-Warning + } + # If you want to stop things, change this to a throw. + # This is not currently throwing as there are two packages that are supposed to fail. + Write-Error "$($packFailures.Count) packages failed to pack." } } From ff7009ee135edcdf7905717dd02a4fda6551f2b4 Mon Sep 17 00:00:00 2001 From: Cory Knox Date: Thu, 26 Sep 2024 11:39:31 -0700 Subject: [PATCH 14/14] (maint) Remove templated values from test packages This commit removes templated values from the test packages being added in this PR. --- .../get-chocolateyunzip-licensed.nuspec | 54 ++++--------------- .../1.0.0/hasfailingnesteddependency.nuspec | 4 +- .../1.0.0/hasnesteddependency.nuspec | 8 +-- .../1.0.0/downgradesdependency.nuspec | 4 +- .../1.0.0/upgradedowngradesdependency.nuspec | 4 +- .../2.0.0/downgradesdependency.nuspec | 4 +- .../2.0.0/upgradedowngradesdependency.nuspec | 4 +- 7 files changed, 23 insertions(+), 59 deletions(-) diff --git a/tests/packages/get-chocolateyunzip-licensed/get-chocolateyunzip-licensed.nuspec b/tests/packages/get-chocolateyunzip-licensed/get-chocolateyunzip-licensed.nuspec index a1daaef7c5..5370f474a7 100755 --- a/tests/packages/get-chocolateyunzip-licensed/get-chocolateyunzip-licensed.nuspec +++ b/tests/packages/get-chocolateyunzip-licensed/get-chocolateyunzip-licensed.nuspec @@ -1,59 +1,23 @@ - - - - - - - - - - - - - get-chocolateyunzip-licensed - - - 3.21.2 - - __REPLACE__ - - - - - __REPLACE__ (Portable) - __REPLACE__ + chocolatey + get-chocolateyunzip-licensed (Portable) + Chocolatey Software - __REPLACE__ + Chocolatey Software get-chocolateyunzip-licensed - __REPLACE__MarkDown_Okay - + + This package contains a commercial edition of the cmdlet `Get-ChocolateyUnzip`, and can be used to verify that installation with that cmdlet works as intended. - - +Additionally it can be tested that the package will fail if being installed on FOSS Edition of Chocolatey. - - - +The package defines the license types `business`, `Education` and `professional` as being valid licenses. + - diff --git a/tests/packages/hasfailingnesteddependency/1.0.0/hasfailingnesteddependency.nuspec b/tests/packages/hasfailingnesteddependency/1.0.0/hasfailingnesteddependency.nuspec index 0479bb03ec..6f13009705 100644 --- a/tests/packages/hasfailingnesteddependency/1.0.0/hasfailingnesteddependency.nuspec +++ b/tests/packages/hasfailingnesteddependency/1.0.0/hasfailingnesteddependency.nuspec @@ -4,8 +4,8 @@ hasfailingnesteddependency 1.0.0 hasfailingnesteddependency - __REPLACE_AUTHORS_OF_SOFTWARE__ - __REPLACE_YOUR_NAME__ + Chocolatey Software + chocolatey false Package that contains dependencies that have dependencies that may fail to install. diff --git a/tests/packages/hasnesteddependency/1.0.0/hasnesteddependency.nuspec b/tests/packages/hasnesteddependency/1.0.0/hasnesteddependency.nuspec index 6e3a0d1ec2..fbc8d2df82 100644 --- a/tests/packages/hasnesteddependency/1.0.0/hasnesteddependency.nuspec +++ b/tests/packages/hasnesteddependency/1.0.0/hasnesteddependency.nuspec @@ -4,11 +4,11 @@ hasnesteddependency 1.0.0 hasnesteddependency - __REPLACE_AUTHORS_OF_SOFTWARE__ - __REPLACE_YOUR_NAME__ + Chocolatey Software + chocolatey false - __REPLACE__ - __REPLACE__ + Package used for testing nested dependencies. + Package used for testing nested dependencies. hasnesteddependency admin diff --git a/tests/packages/upgradedowngradesdependency/1.0.0/downgradesdependency.nuspec b/tests/packages/upgradedowngradesdependency/1.0.0/downgradesdependency.nuspec index 142b308132..0ad0f09d93 100644 --- a/tests/packages/upgradedowngradesdependency/1.0.0/downgradesdependency.nuspec +++ b/tests/packages/upgradedowngradesdependency/1.0.0/downgradesdependency.nuspec @@ -4,8 +4,8 @@ downgradesdependency 1.0.0 Has out of range Dependency - __REPLACE_AUTHORS_OF_SOFTWARE__ - __REPLACE_YOUR_NAME__ + Chocolatey Software + chocolatey false These packages can be used to test the installation or upgrading of packages that require an existing package to downgrade. diff --git a/tests/packages/upgradedowngradesdependency/1.0.0/upgradedowngradesdependency.nuspec b/tests/packages/upgradedowngradesdependency/1.0.0/upgradedowngradesdependency.nuspec index a18dfdf619..bb723ce36e 100644 --- a/tests/packages/upgradedowngradesdependency/1.0.0/upgradedowngradesdependency.nuspec +++ b/tests/packages/upgradedowngradesdependency/1.0.0/upgradedowngradesdependency.nuspec @@ -4,8 +4,8 @@ upgradedowngradesdependency 1.0.0 Has out of range Dependency - __REPLACE_AUTHORS_OF_SOFTWARE__ - __REPLACE_YOUR_NAME__ + Chocolatey Software + chocolatey false These packages can be used to test the installation or upgrading of packages that require an existing package to downgrade. diff --git a/tests/packages/upgradedowngradesdependency/2.0.0/downgradesdependency.nuspec b/tests/packages/upgradedowngradesdependency/2.0.0/downgradesdependency.nuspec index 42229dc482..efccc67761 100644 --- a/tests/packages/upgradedowngradesdependency/2.0.0/downgradesdependency.nuspec +++ b/tests/packages/upgradedowngradesdependency/2.0.0/downgradesdependency.nuspec @@ -4,8 +4,8 @@ downgradesdependency 2.0.0 Has out of range Dependency (Below available) - __REPLACE_AUTHORS_OF_SOFTWARE__ - __REPLACE_YOUR_NAME__ + Chocolatey Software + chocolatey false These packages can be used to test the installation or upgrading of packages that require an existing package to downgrade. diff --git a/tests/packages/upgradedowngradesdependency/2.0.0/upgradedowngradesdependency.nuspec b/tests/packages/upgradedowngradesdependency/2.0.0/upgradedowngradesdependency.nuspec index 58b125b3e7..e00f3c9dea 100644 --- a/tests/packages/upgradedowngradesdependency/2.0.0/upgradedowngradesdependency.nuspec +++ b/tests/packages/upgradedowngradesdependency/2.0.0/upgradedowngradesdependency.nuspec @@ -4,8 +4,8 @@ upgradedowngradesdependency 2.0.0 Has out of range Dependency (Below available) - __REPLACE_AUTHORS_OF_SOFTWARE__ - __REPLACE_YOUR_NAME__ + Chocolatey Software + chocolatey false These packages can be used to test the installation or upgrading of packages that require an existing package to downgrade.