diff --git a/src/code/FindHelper.cs b/src/code/FindHelper.cs index 5c5088f58..cc7d08462 100644 --- a/src/code/FindHelper.cs +++ b/src/code/FindHelper.cs @@ -95,6 +95,7 @@ public IEnumerable FindByResourceName( } _pkgsLeftToFind = new List(name); + _tagsLeftToFind = tag == null ? new List() : new List(tag); // Error out if repository array of names to be searched contains wildcards. if (repository != null) @@ -975,7 +976,7 @@ private IEnumerable FindFromPackageSourceSearchAPI( List wildcardPkgs; try { - string wildcardPkgName = pkgName.Equals("*") ? string.Empty : pkgName; + string wildcardPkgName = string.Empty; // SearchAsync() API returns the latest version only for all packages that match the wild-card name wildcardPkgs = pkgSearchResource.SearchAsync( searchTerm: wildcardPkgName, diff --git a/src/code/InstallHelper.cs b/src/code/InstallHelper.cs index 21acf4ce5..83968e4ec 100644 --- a/src/code/InstallHelper.cs +++ b/src/code/InstallHelper.cs @@ -136,8 +136,9 @@ public IEnumerable InstallPackages( { _versionType = VersionType.SpecificVersion; } - else if (!parsedAsNuGetVersion && _versionRange == null) + else if (!parsedAsNuGetVersion && _versionRange == null || _versionRange == VersionRange.All) { + // if VersionRange == VersionRange.All then we wish to get latest package only (effectively disregard version) _versionType = VersionType.NoVersion; } else @@ -417,49 +418,52 @@ private List HttpInstall( FindHelper findHelper) { List pkgsSuccessfullyInstalled = new List(); - NuGetVersion nugetVersion = null; - VersionRange versionRange= null; - VersionType currentType; + // NuGetVersion nugetVersion = null; + // VersionRange versionRange= null; + // VersionType currentType; - if (!String.IsNullOrEmpty(_versionString)) - { - if (_versionString.Contains("*")) - { - _cmdletPassedIn.WriteError(new ErrorRecord( - new ArgumentException("Argument for -Version parameter cannot contain wildcards."), - "VersionCannotContainWildcard", - ErrorCategory.InvalidArgument, - this)); + // if (!String.IsNullOrEmpty(_versionString)) + // { + // if (_versionString.Equals("*")) + // { + // currentType = VersionType.NoVersion; + // } + // else if (_versionString.Contains("*")) + // { + // _cmdletPassedIn.WriteError(new ErrorRecord( + // new ArgumentException("Argument for -Version parameter cannot contain wildcards."), + // "VersionCannotContainWildcard", + // ErrorCategory.InvalidArgument, + // this)); - return pkgsSuccessfullyInstalled; - } - - if (!NuGetVersion.TryParse(_versionString, out nugetVersion)) - { - if (!VersionRange.TryParse(_versionString, out versionRange)) - { - _cmdletPassedIn.WriteError(new ErrorRecord( - new ArgumentException("Argument for -Version parameter is not in the proper format"), - "IncorrectVersionFormat", - ErrorCategory.InvalidArgument, - this)); + // return pkgsSuccessfullyInstalled; + // } + // else if (!NuGetVersion.TryParse(_versionString, out nugetVersion)) + // { + // if (!VersionRange.TryParse(_versionString, out versionRange)) + // { + // _cmdletPassedIn.WriteError(new ErrorRecord( + // new ArgumentException("Argument for -Version parameter is not in the proper format"), + // "IncorrectVersionFormat", + // ErrorCategory.InvalidArgument, + // this)); - return pkgsSuccessfullyInstalled; - } - else - { - currentType = VersionType.VersionRange; - } - } - else - { - currentType = VersionType.SpecificVersion; - } - } - else - { - currentType = VersionType.NoVersion; - } + // return pkgsSuccessfullyInstalled; + // } + // else + // { + // currentType = VersionType.VersionRange; + // } + // } + // else + // { + // currentType = VersionType.SpecificVersion; + // } + // } + // else + // { + // currentType = VersionType.NoVersion; + // } // Install parent package to the temp directory, // Get the dependencies from the installed package, @@ -476,9 +480,9 @@ private List HttpInstall( // packageName, { version = "", isScript = "", isModule = "", pkg = "", etc. } // Install parent package to the temp directory. Hashtable packagesHash = HttpInstallPackage( - searchVersionType: currentType, - specificVersion: nugetVersion, - versionRange: versionRange, + searchVersionType: _versionType, + specificVersion: _nugetVersion, + versionRange: _versionRange, pkgNameToInstall: parentPackage, repository: repository, currentServer: currentServer, @@ -491,6 +495,7 @@ private List HttpInstall( if (edi != null) { _cmdletPassedIn.WriteError(new ErrorRecord(edi.SourceException, "InstallPackageFailure", ErrorCategory.InvalidOperation, this)); + continue; } if (packagesHash.Count == 0) { @@ -517,10 +522,20 @@ private List HttpInstall( { continue; } + + NuGetVersion depVersion = null; + if (depPkg.AdditionalMetadata.ContainsKey("NormalizedVersion")) + { + if (!NuGetVersion.TryParse(depPkg.AdditionalMetadata["NormalizedVersion"] as string, out depVersion)) + { + NuGetVersion.TryParse(depPkg.Version.ToString(), out depVersion); // TODO: Anam write error here if false + } + } + packagesHash = HttpInstallPackage( - searchVersionType: currentType, - specificVersion: nugetVersion, - versionRange: versionRange, + searchVersionType: VersionType.SpecificVersion, + specificVersion: depVersion, + versionRange: null, pkgNameToInstall: depPkg.Name, repository: repository, currentServer: currentServer, @@ -532,6 +547,7 @@ private List HttpInstall( if (installPackageEdi != null) { _cmdletPassedIn.WriteError(new ErrorRecord(installPackageEdi.SourceException, "InstallDependencyPackageFailure", ErrorCategory.InvalidOperation, this)); + continue; } } } @@ -587,8 +603,8 @@ private Hashtable HttpInstallPackage( { case VersionType.VersionRange: responses = currentServer.FindVersionGlobbing(pkgNameToInstall, versionRange, _prerelease, ResourceType.None, getOnlyLatest: true, out ExceptionDispatchInfo findVersionGlobbingEdi); - - if (findVersionGlobbingEdi != null) + // Server level globbing API will not populate edi for empty response, so must check for empty response and early out + if (findVersionGlobbingEdi != null || responses.Length == 0) { edi = findVersionGlobbingEdi; return packagesHash; @@ -626,25 +642,30 @@ private Hashtable HttpInstallPackage( if (!String.IsNullOrEmpty(currentResult.errorMsg)) { - //edi = ExceptionDispatchInfo.Capture(new InvalidOperationException(currentResult.errorMsg)); + // V2Server API calls will return non-empty response when package is not found but fail at conversion time + edi = ExceptionDispatchInfo.Capture(new InvalidOrEmptyResponse($"Package for installation could not be found due to: {currentResult.errorMsg}")); return packagesHash; } PSResourceInfo pkgToInstall = currentResult.returnedObject; pkgToInstall.RepositorySourceLocation = repository.Uri.ToString(); + pkgToInstall.AdditionalMetadata.TryGetValue("NormalizedVersion", out string pkgVersion); // Check to see if the pkg is already installed (ie the pkg is installed and the version satisfies the version range provided via param) if (!_reinstall) { string currPkgNameVersion = Utils.CreateHashSetKey(pkgToInstall.Name, pkgToInstall.Version.ToString()); if (_packagesOnMachine.Contains(currPkgNameVersion)) - { + { + _cmdletPassedIn.WriteWarning( + string.Format("Resource '{0}' with version '{1}' is already installed. If you would like to reinstall, please run the cmdlet again with the -Reinstall parameter", + pkgToInstall.Name, + pkgVersion)); return packagesHash; } } // Download the package. - pkgToInstall.AdditionalMetadata.TryGetValue("NormalizedVersion", out string pkgVersion); string pkgName = pkgToInstall.Name; HttpContent responseContent = null; @@ -670,12 +691,13 @@ private Hashtable HttpInstallPackage( } Hashtable updatedPackagesHash; - bool installedToTempPathSuccessfully = _asNupkg ? TrySaveNupkgToTempPath(responseContent, tempInstallPath, pkgName, pkgVersion, pkgToInstall, packagesHash, out updatedPackagesHash) : - TryInstallToTempPath(responseContent, tempInstallPath, pkgName, pkgVersion, pkgToInstall, packagesHash, out updatedPackagesHash); - + ErrorRecord error = null; + bool installedToTempPathSuccessfully = _asNupkg ? TrySaveNupkgToTempPath(responseContent, tempInstallPath, pkgName, pkgVersion, pkgToInstall, packagesHash, out updatedPackagesHash, out error) : + TryInstallToTempPath(responseContent, tempInstallPath, pkgName, pkgVersion, pkgToInstall, packagesHash, out updatedPackagesHash, out error); + if (!installedToTempPathSuccessfully) { - edi = ExceptionDispatchInfo.Capture(new System.Exception(currentResult.errorMsg)); + edi = ExceptionDispatchInfo.Capture(error.Exception); return packagesHash; } @@ -701,6 +723,7 @@ private string CreateInstallationTempPath() } catch (Exception e) { + // catch more specific exception first _cmdletPassedIn.ThrowTerminatingError(new ErrorRecord( new ArgumentException($"Temporary folder for installation could not be created or set due to: {e.Message}"), "TempFolderCreationError", @@ -741,8 +764,10 @@ private bool TryInstallToTempPath( string normalizedPkgVersion, PSResourceInfo pkgToInstall, Hashtable packagesHash, - out Hashtable updatedPackagesHash) + out Hashtable updatedPackagesHash, + out ErrorRecord error) { + error = null; updatedPackagesHash = packagesHash; // Take response content for HTTPInstallPackage and move files into temp install path. try @@ -777,9 +802,10 @@ private bool TryInstallToTempPath( pkgName, tempDirNameVersion, _cmdletPassedIn, - out ErrorRecord errorRecord)) + out error)) { - _cmdletPassedIn.ThrowTerminatingError(errorRecord); + return false; + // _cmdletPassedIn.ThrowTerminatingError(errorRecord); } string installPath = string.Empty; @@ -792,8 +818,7 @@ private bool TryInstallToTempPath( var message = String.Format("{0} package could not be installed with error: Module manifest file: {1} does not exist. This is not a valid PowerShell module.", pkgName, moduleManifest); var ex = new ArgumentException(message); - var psdataFileDoesNotExistError = new ErrorRecord(ex, "psdataFileNotExistError", ErrorCategory.ReadError, null); - _cmdletPassedIn.WriteError(psdataFileDoesNotExistError); + error = new ErrorRecord(ex, "psdataFileNotExistError", ErrorCategory.ReadError, null); _pkgNamesToInstall.RemoveAll(x => x.Equals(pkgName, StringComparison.InvariantCultureIgnoreCase)); return false; @@ -804,25 +829,26 @@ private bool TryInstallToTempPath( manifestInfo: out Hashtable parsedMetadataHashtable, error: out Exception manifestReadError)) { - _cmdletPassedIn.WriteError( - new ErrorRecord( - exception: manifestReadError, - errorId: "ManifestFileReadParseError", - errorCategory: ErrorCategory.ReadError, - this)); + error = new ErrorRecord( + exception: manifestReadError, + errorId: "ManifestFileReadParseError", + errorCategory: ErrorCategory.ReadError, + this); return false; } // Accept License verification - if (!_savePkg && !CallAcceptLicense(pkgToInstall, moduleManifest, tempInstallPath, pkgVersion)) + if (!_savePkg && !CallAcceptLicense(pkgToInstall, moduleManifest, tempInstallPath, pkgVersion, out error)) { + _pkgNamesToInstall.RemoveAll(x => x.Equals(pkgToInstall.Name, StringComparison.InvariantCultureIgnoreCase)); return false; } // If NoClobber is specified, ensure command clobbering does not happen - if (_noClobber && !DetectClobber(pkgName, parsedMetadataHashtable)) + if (_noClobber && DetectClobber(pkgName, parsedMetadataHashtable, out error)) { + _pkgNamesToInstall.RemoveAll(x => x.Equals(pkgName, StringComparison.InvariantCultureIgnoreCase)); return false; } } @@ -834,13 +860,17 @@ private bool TryInstallToTempPath( if (!PSScriptFileInfo.TryTestPSScriptFile( scriptFileInfoPath: scriptPath, parsedScript: out PSScriptFileInfo scriptToInstall, - out ErrorRecord[] errors, + out ErrorRecord[] parseScriptFileErrors, out string[] _)) { - foreach (ErrorRecord error in errors) + foreach (ErrorRecord parseError in parseScriptFileErrors) { - _cmdletPassedIn.WriteError(error); + _cmdletPassedIn.WriteError(parseError); } + + var ex = new InvalidOperationException($"PSScriptFile could not be parsed"); + error = new ErrorRecord(ex, "psScriptParseError", ErrorCategory.ReadError, null); + _pkgNamesToInstall.RemoveAll(x => x.Equals(pkgName, StringComparison.InvariantCultureIgnoreCase)); return false; } @@ -859,7 +889,11 @@ private bool TryInstallToTempPath( if (_includeXml) { - CreateMetadataXMLFile(tempDirNameVersion, installPath, pkgToInstall, isModule); + if (!CreateMetadataXMLFile(tempDirNameVersion, installPath, pkgToInstall, isModule, out error)) + { + _pkgNamesToInstall.RemoveAll(x => x.Equals(pkgToInstall.Name, StringComparison.InvariantCultureIgnoreCase)); + return false; + } } if (!updatedPackagesHash.ContainsKey(pkgName)) @@ -881,14 +915,22 @@ private bool TryInstallToTempPath( } catch (Exception e) { - _cmdletPassedIn.WriteError( - new ErrorRecord( - new PSInvalidOperationException( - message: $"Unable to successfully install package '{pkgName}': '{e.Message}' to temporary installation path.", - innerException: e), - "InstallPackageFailed", - ErrorCategory.InvalidOperation, - _cmdletPassedIn)); + error = new ErrorRecord( + new PSInvalidOperationException( + message: $"Unable to successfully install package '{pkgName}': '{e.Message}' to temporary installation path.", + innerException: e), + "InstallPackageFailed", + ErrorCategory.InvalidOperation, + _cmdletPassedIn); + + // _cmdletPassedIn.WriteError( + // new ErrorRecord( + // new PSInvalidOperationException( + // message: $"Unable to successfully install package '{pkgName}': '{e.Message}' to temporary installation path.", + // innerException: e), + // "InstallPackageFailed", + // ErrorCategory.InvalidOperation, + // _cmdletPassedIn)); _pkgNamesToInstall.RemoveAll(x => x.Equals(pkgName, StringComparison.InvariantCultureIgnoreCase)); return false; } @@ -904,9 +946,12 @@ private bool TrySaveNupkgToTempPath( string normalizedPkgVersion, PSResourceInfo pkgToInstall, Hashtable packagesHash, - out Hashtable updatedPackagesHash) + out Hashtable updatedPackagesHash, + out ErrorRecord error) { + error = null; updatedPackagesHash = packagesHash; + // Take response content for HTTPInstallPackage and move .nupkg into temp install path. try { @@ -920,7 +965,11 @@ private bool TrySaveNupkgToTempPath( string installPath = _pathsToInstallPkg.First(); if (_includeXml) { - CreateMetadataXMLFile(tempInstallPath, installPath, pkgToInstall, isModule: true); + if (!CreateMetadataXMLFile(tempInstallPath, installPath, pkgToInstall, isModule: true, out error)) + { + _pkgNamesToInstall.RemoveAll(x => x.Equals(pkgName, StringComparison.InvariantCultureIgnoreCase)); + return false; + } } if (!updatedPackagesHash.ContainsKey(pkgName)) @@ -942,14 +991,22 @@ private bool TrySaveNupkgToTempPath( } catch (Exception e) { - _cmdletPassedIn.WriteError( - new ErrorRecord( - new PSInvalidOperationException( - message: $"Unable to successfully save .nupkg '{pkgName}': '{e.Message}' to temporary installation path.", - innerException: e), + error = new ErrorRecord( + new PSInvalidOperationException( + message: $"Unable to successfully save .nupkg '{pkgName}': '{e.Message}' to temporary installation path.", + innerException: e), "SaveNupkgFailed", ErrorCategory.InvalidOperation, - _cmdletPassedIn)); + _cmdletPassedIn); + + // _cmdletPassedIn.WriteError( + // new ErrorRecord( + // new PSInvalidOperationException( + // message: $"Unable to successfully save .nupkg '{pkgName}': '{e.Message}' to temporary installation path.", + // innerException: e), + // "SaveNupkgFailed", + // ErrorCategory.InvalidOperation, + // _cmdletPassedIn)); _pkgNamesToInstall.RemoveAll(x => x.Equals(pkgName, StringComparison.InvariantCultureIgnoreCase)); return false; } @@ -1102,7 +1159,9 @@ private List InstallPackage( if (_asNupkg) { - _cmdletPassedIn.WriteWarning("This feature is not yet implemented."); + _cmdletPassedIn.WriteWarning("Saving resource from local/file based repository with -AsNupkg is not yet implemented feature."); + _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); + continue; } else { @@ -1213,14 +1272,18 @@ private List InstallPackage( pkg.RepositorySourceLocation = repoUri; // Accept License verification - if (!_savePkg && !CallAcceptLicense(pkg, moduleManifest, tempInstallPath, newVersion)) + if (!_savePkg && !CallAcceptLicense(pkg, moduleManifest, tempInstallPath, newVersion, out ErrorRecord licenseError)) { + _cmdletPassedIn.WriteError(licenseError); + _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); continue; } // If NoClobber is specified, ensure command clobbering does not happen - if (_noClobber && !DetectClobber(pkg.Name, parsedMetadataHashtable)) + if (_noClobber && DetectClobber(pkg.Name, parsedMetadataHashtable, out ErrorRecord clobberError)) { + _cmdletPassedIn.WriteError(clobberError); + _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); continue; } } @@ -1239,6 +1302,7 @@ out string[] _ _cmdletPassedIn.WriteError(error); } + _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); continue; } @@ -1256,7 +1320,13 @@ out string[] _ if (_includeXml) { - CreateMetadataXMLFile(tempDirNameVersion, installPath, pkg, isModule); + if (!CreateMetadataXMLFile(tempDirNameVersion, installPath, pkg, isModule, out ErrorRecord createMetadataError)) + { + _cmdletPassedIn.WriteError(createMetadataError); + _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); + continue; + } + } MoveFilesIntoInstallPath( @@ -1319,8 +1389,9 @@ out string[] _ return pkgsSuccessfullyInstalled; } - private bool CallAcceptLicense(PSResourceInfo p, string moduleManifest, string tempInstallPath, string newVersion) + private bool CallAcceptLicense(PSResourceInfo p, string moduleManifest, string tempInstallPath, string newVersion, out ErrorRecord error) { + error = null; var requireLicenseAcceptance = false; var success = true; @@ -1357,10 +1428,13 @@ private bool CallAcceptLicense(PSResourceInfo p, string moduleManifest, string t var exMessage = String.Format("{0} package could not be installed with error: License.txt not found. License.txt must be provided when user license acceptance is required.", p.Name); var ex = new ArgumentException(exMessage); var acceptLicenseError = new ErrorRecord(ex, "LicenseTxtNotFound", ErrorCategory.ObjectNotFound, null); + error = acceptLicenseError; - _cmdletPassedIn.WriteError(acceptLicenseError); - _pkgNamesToInstall.RemoveAll(x => x.Equals(p.Name, StringComparison.InvariantCultureIgnoreCase)); + // _cmdletPassedIn.WriteError(acceptLicenseError); + // _pkgNamesToInstall.RemoveAll(x => x.Equals(p.Name, StringComparison.InvariantCultureIgnoreCase)); success = false; + return success; + // TODO: Anam should there be a return here? } // Otherwise read LicenseFile @@ -1385,9 +1459,10 @@ private bool CallAcceptLicense(PSResourceInfo p, string moduleManifest, string t var message = String.Format("{0} package could not be installed with error: License Acceptance is required for module '{0}'. Please specify '-AcceptLicense' to perform this operation.", p.Name); var ex = new ArgumentException(message); var acceptLicenseError = new ErrorRecord(ex, "ForceAcceptLicense", ErrorCategory.InvalidArgument, null); + error = acceptLicenseError; - _cmdletPassedIn.WriteError(acceptLicenseError); - _pkgNamesToInstall.RemoveAll(x => x.Equals(p.Name, StringComparison.InvariantCultureIgnoreCase)); + // _cmdletPassedIn.WriteError(acceptLicenseError); + // _pkgNamesToInstall.RemoveAll(x => x.Equals(p.Name, StringComparison.InvariantCultureIgnoreCase)); success = false; } } @@ -1396,8 +1471,9 @@ private bool CallAcceptLicense(PSResourceInfo p, string moduleManifest, string t return success; } - private bool DetectClobber(string pkgName, Hashtable parsedMetadataHashtable) + private bool DetectClobber(string pkgName, Hashtable parsedMetadataHashtable, out ErrorRecord error) { + error = null; // Get installed modules, then get all possible paths bool foundClobber = false; GetHelper getHelper = new GetHelper(_cmdletPassedIn); @@ -1442,9 +1518,9 @@ private bool DetectClobber(string pkgName, Hashtable parsedMetadataHashtable) var ex = new ArgumentException(errMessage); var noClobberError = new ErrorRecord(ex, "CommandAlreadyExists", ErrorCategory.ResourceExists, null); - - _cmdletPassedIn.WriteError(noClobberError); - _pkgNamesToInstall.RemoveAll(x => x.Equals(pkgName, StringComparison.InvariantCultureIgnoreCase)); + error = noClobberError; + // _cmdletPassedIn.WriteError(noClobberError); + // _pkgNamesToInstall.RemoveAll(x => x.Equals(pkgName, StringComparison.InvariantCultureIgnoreCase)); foundClobber = true; return foundClobber; @@ -1454,8 +1530,10 @@ private bool DetectClobber(string pkgName, Hashtable parsedMetadataHashtable) return foundClobber; } - private void CreateMetadataXMLFile(string dirNameVersion, string installPath, PSResourceInfo pkg, bool isModule) + private bool CreateMetadataXMLFile(string dirNameVersion, string installPath, PSResourceInfo pkg, bool isModule, out ErrorRecord error) { + error = null; + bool success = true; // Script will have a metadata file similar to: "TestScript_InstalledScriptInfo.xml" // Modules will have the metadata file: "PSGetModuleInfo.xml" var metadataXMLPath = isModule ? Path.Combine(dirNameVersion, "PSGetModuleInfo.xml") @@ -1465,15 +1543,17 @@ private void CreateMetadataXMLFile(string dirNameVersion, string installPath, PS pkg.InstalledLocation = installPath; // Write all metadata into metadataXMLPath - if (!pkg.TryWrite(metadataXMLPath, out string error)) + if (!pkg.TryWrite(metadataXMLPath, out string writeError)) { - var message = string.Format("{0} package could not be installed with error: Error parsing metadata into XML: '{1}'", pkg.Name, error); + var message = string.Format("{0} package could not be installed with error: Error parsing metadata into XML: '{1}'", pkg.Name, writeError); var ex = new ArgumentException(message); - var ErrorParsingMetadata = new ErrorRecord(ex, "ErrorParsingMetadata", ErrorCategory.ParserError, null); - - _cmdletPassedIn.WriteError(ErrorParsingMetadata); - _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); + var errorParsingMetadata = new ErrorRecord(ex, "ErrorParsingMetadata", ErrorCategory.ParserError, null); + error = errorParsingMetadata; + // _cmdletPassedIn.WriteError(ErrorParsingMetadata); + // _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); } + + return success; } private void DeleteExtraneousFiles(string packageName, string dirNameVersion) diff --git a/src/code/PSGetException.cs b/src/code/PSGetException.cs index 365aeee61..c714d1ac9 100644 --- a/src/code/PSGetException.cs +++ b/src/code/PSGetException.cs @@ -37,4 +37,12 @@ public SpecifiedTagsNotFoundException(string message) { } } + + public class InvalidOrEmptyResponse : Exception + { + public InvalidOrEmptyResponse(string message) + : base (message) + { + } + } } diff --git a/src/code/Utils.cs b/src/code/Utils.cs index 14e4dbbdc..d62979bcd 100644 --- a/src/code/Utils.cs +++ b/src/code/Utils.cs @@ -239,7 +239,6 @@ public static bool TryParseVersionOrVersionRange( return true; } - // parse as Version range return VersionRange.TryParse(version, out versionRange); } diff --git a/src/code/V3ServerAPICalls.cs b/src/code/V3ServerAPICalls.cs index a7309c997..64a83da77 100644 --- a/src/code/V3ServerAPICalls.cs +++ b/src/code/V3ServerAPICalls.cs @@ -234,6 +234,11 @@ public override string FindName(string packageName, bool includePrerelease, Reso } } + if (String.IsNullOrEmpty(response)) + { + edi = ExceptionDispatchInfo.Capture(new InvalidOrEmptyResponse($"FindName() with {packageName} returned empty response.")); + } + return response; } @@ -293,6 +298,11 @@ public override string FindNameWithTag(string packageName, string[] tags, bool i } } + if (String.IsNullOrEmpty(response)) + { + edi = ExceptionDispatchInfo.Capture(new InvalidOrEmptyResponse($"FindNameWithTag() with {packageName} and tags {String.Join(",", tags)} returned empty response.")); + } + return response; } @@ -610,6 +620,11 @@ public override string FindVersion(string packageName, string version, ResourceT return String.Empty; } + if (String.IsNullOrEmpty(response)) + { + edi = ExceptionDispatchInfo.Capture(new InvalidOrEmptyResponse($"FindVersion() with {packageName} and version {version} returned empty response.")); + } + return response; } @@ -642,6 +657,11 @@ public override string FindVersionWithTag(string packageName, string version, st return String.Empty; } + if (String.IsNullOrEmpty(response)) + { + edi = ExceptionDispatchInfo.Capture(new InvalidOrEmptyResponse($"FindVersion() with {packageName}, tags {String.Join(", ", tags)} and version {version} returned empty response.")); + } + return response; } diff --git a/test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1 b/test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1 new file mode 100644 index 000000000..65c7e0fff --- /dev/null +++ b/test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1 @@ -0,0 +1,208 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +Import-Module "$((Get-Item $psscriptroot).parent)\PSGetTestUtils.psm1" -Force + +Describe 'Test HTTP Find-PSResource for Module' { + + BeforeAll{ + $localRepo = "psgettestlocal" + $testModuleName = "test_local_mod" + $testModuleName2 = "test_local_mod2" + $commandName = "cmd1" + $dscResourceName = "dsc1" + $cmdName = "PSCommand_$commandName" + $dscName = "PSDscResource_$dscResourceName" + $prereleaseLabel = "" + Get-NewPSResourceRepositoryFile + Register-LocalRepos + + $tags = @("Test", "Tag2", $cmdName, $dscName) + Get-ModuleResourcePublishedToLocalRepoTestDrive $testModuleName $localRepo "1.0.0" + Get-ModuleResourcePublishedToLocalRepoTestDrive $testModuleName $localRepo "3.0.0" + Get-ModuleResourcePublishedToLocalRepoTestDrive $testModuleName $localRepo "5.0.0" $prereleaseLabel $tags + Get-ModuleResourcePublishedToLocalRepoTestDrive $testModuleName2 $localRepo "5.0.0" $prereleaseLabel $tags + + $prereleaseLabel = "alpha001" + $params = @{ + moduleName = $testModuleName + repoName = $localRepo + packageVersion = "5.2.5" + prereleaseLabel = $prereleaseLabel + tags = $tags + } + Get-ModuleResourcePublishedToLocalRepoTestDrive @params + } + + AfterAll { + Get-RevertPSResourceRepositoryFile + } + + It "find resource given specific Name, Version null" { + # FindName() + $res = Find-PSResource -Name $testModuleName -Repository $localRepo + $res.Name | Should -Be $testModuleName + $res.Version | Should -Be "5.0.0.0" + } + + It "should not find resource given nonexistant Name" { + $res = Find-PSResource -Name NonExistantModule -Repository $localRepo + $res | Should -BeNullOrEmpty + } + + # It "find resource(s) given wildcard Name" { + # # FindNameGlobbing + # $res = Find-PSResource -Name "test_local_*" -Repository $localRepo + # $res.Count | Should -BeGreaterThan 1 + # } + + $testCases2 = @{Version="[5.0.0.0]"; ExpectedVersions=@("5.0.0.0"); Reason="validate version, exact match"}, + @{Version="5.0.0.0"; ExpectedVersions=@("5.0.0.0"); Reason="validate version, exact match without bracket syntax"}, + @{Version="[1.0.0.0, 5.0.0.0]"; ExpectedVersions=@("1.0.0.0", "3.0.0.0", "5.0.0.0"); Reason="validate version, exact range inclusive"}, + @{Version="(1.0.0.0, 5.0.0.0)"; ExpectedVersions=@("3.0.0.0"); Reason="validate version, exact range exclusive"}, + @{Version="(1.0.0.0,)"; ExpectedVersions=@("3.0.0.0", "5.0.0.0"); Reason="validate version, minimum version exclusive"}, + @{Version="[1.0.0.0,)"; ExpectedVersions=@("1.0.0.0", "3.0.0.0", "5.0.0.0"); Reason="validate version, minimum version inclusive"}, + @{Version="(,3.0.0.0)"; ExpectedVersions=@("1.0.0.0"); Reason="validate version, maximum version exclusive"}, + @{Version="(,3.0.0.0]"; ExpectedVersions=@("1.0.0.0", "3.0.0.0"); Reason="validate version, maximum version inclusive"}, + @{Version="[1.0.0.0, 5.0.0.0)"; ExpectedVersions=@("1.0.0.0", "3.0.0.0"); Reason="validate version, mixed inclusive minimum and exclusive maximum version"} + @{Version="(1.0.0.0, 5.0.0.0]"; ExpectedVersions=@("3.0.0.0", "5.0.0.0"); Reason="validate version, mixed exclusive minimum and inclusive maximum version"} + + It "find resource when given Name to " -TestCases $testCases2{ + # FindVersionGlobbing() + param($Version, $ExpectedVersions) + $res = Find-PSResource -Name $testModuleName -Version $Version -Repository $localRepo + foreach ($item in $res) { + $item.Name | Should -Be $testModuleName + $ExpectedVersions | Should -Contain $item.Version + } + } + + It "find all versions of resource when given specific Name, Version not null --> '*'" { + # FindVersionGlobbing() + $res = Find-PSResource -Name $testModuleName -Version "*" -Repository $localRepo + $res | ForEach-Object { + $_.Name | Should -Be $testModuleName + } + + $res.Count | Should -BeGreaterOrEqual 1 + } + + It "find resource with latest (including prerelease) version given Prerelease parameter" { + # FindName() + # test_module resource's latest version is a prerelease version, before that it has a non-prerelease version + $res = Find-PSResource -Name $testModuleName -Repository $localRepo + $res.Version | Should -Be "5.0.0.0" + + $resPrerelease = Find-PSResource -Name $testModuleName -Prerelease -Repository $localRepo + $resPrerelease.Version | Should -Be "5.2.5.0" + $resPrerelease.Prerelease | Should -Be "alpha001" + } + + It "find resources, including Prerelease version resources, when given Prerelease parameter" { + # FindVersionGlobbing() + $resWithoutPrerelease = Find-PSResource -Name $testModuleName -Version "*" -Repository $localRepo + $resWithPrerelease = Find-PSResource -Name $testModuleName -Version "*" -Repository $localRepo + $resWithPrerelease.Count | Should -BeGreaterOrEqual $resWithoutPrerelease.Count + } + + It "find resource that satisfies given Name and Tag property (single tag)" { + # FindNameWithTag() + $requiredTag = "test" + $res = Find-PSResource -Name $testModuleName -Tag $requiredTag -Repository $localRepo + $res.Name | Should -Be $testModuleName + $res.Tags | Should -Contain $requiredTag + } + + It "should not find resource if Name and Tag are not both satisfied (single tag)" { + # FindNameWithTag + $requiredTag = "Windows" # tag "windows" is not present for test_module package + $res = Find-PSResource -Name $testModuleName -Tag $requiredTag -Repository $localRepo + $res | Should -BeNullOrEmpty + } + + It "find resource that satisfies given Name and Tag property (multiple tags)" { + # FindNameWithTag() + $requiredTags = @("test", "Tag2") + $res = Find-PSResource -Name $testModuleName -Tag $requiredTags -Repository $localRepo + $res.Name | Should -Be $testModuleName + $res.Tags | Should -Contain $requiredTags[0] + $res.Tags | Should -Contain $requiredTags[1] + } + + It "find all resources that satisfy Name pattern and have specified Tag (single tag)" { + # FindNameGlobbingWithTag() + $requiredTag = "test" + $nameWithWildcard = "test_local_mod*" + $res = Find-PSResource -Name $nameWithWildcard -Tag $requiredTag -Repository $localRepo + $res.Count | Should -BeGreaterThan 1 + foreach ($pkg in $res) + { + $pkg.Name | Should -BeLike $nameWithWildcard + $pkg.Tags | Should -Contain $requiredTag + } + } + + It "should not find resources if both Name pattern and Tags are not satisfied (single tag)" { + # FindNameGlobbingWithTag() + $requiredTag = "windows" # tag "windows" is not present for test_module package + $res = Find-PSResource -Name "test_module*" -Tag $requiredTag -Repository $localRepo + $res | Should -BeNullOrEmpty + } + + It "find all resources that satisfy Name pattern and have specified Tag (multiple tags)" { + # FindNameGlobbingWithTag() + $requiredTags = @("test", "Tag2") + $nameWithWildcard = "test_local_mod*" + $res = Find-PSResource -Name $nameWithWildcard -Tag $requiredTags -Repository $localRepo + $res.Count | Should -BeGreaterThan 1 + foreach ($pkg in $res) + { + $pkg.Name | Should -BeLike $nameWithWildcard + $pkg.Tags | Should -Contain $requiredTags[0] + $pkg.Tags | Should -Contain $requiredTags[1] + } + } + + It "find resource that satisfies given Name, Version and Tag property (single tag)" { + # FindVersionWithTag() + $requiredTag = "test" + $res = Find-PSResource -Name $testModuleName -Version "5.0.0.0" -Tag $requiredTag -Repository $localRepo + $res.Name | Should -Be $testModuleName + $res.Version | Should -Be "5.0.0.0" + $res.Tags | Should -Contain $requiredTag + } + + It "should not find resource if Name, Version and Tag property are not all satisfied (single tag)" { + # FindVersionWithTag() + $requiredTag = "windows" # tag "windows" is not present for test_module package + $res = Find-PSResource -Name $testModuleName -Version "5.0.0.0" -Tag $requiredTag -Repository $localRepo + $res | Should -BeNullOrEmpty + } + + It "find resource that satisfies given Name, Version and Tag property (multiple tags)" { + # FindVersionWithTag() + $requiredTags = @("test", "Tag2") + $res = Find-PSResource -Name $testModuleName -Version "5.0.0.0" -Tag $requiredTags -Repository $localRepo + $res.Name | Should -Be $testModuleName + $res.Version | Should -Be "5.0.0.0" + $res.Tags | Should -Contain $requiredTags[0] + $res.Tags | Should -Contain $requiredTags[1] + + } + + It "find resource given CommandName" { + $res = Find-PSResource -CommandName $commandName -Repository $localRepo + foreach ($item in $res) { + $item.Names | Should -Be $commandName + $item.ParentResource.Includes.Command | Should -Contain $commandName + } + } + + It "find resource given DscResourceName" { + $res = Find-PSResource -DscResourceName $dscResourceName -Repository $localRepo + foreach ($item in $res) { + $item.Names | Should -Be $dscResourceName + $item.ParentResource.Includes.DscResource | Should -Contain $dscResourceName + } + } +} diff --git a/test/FindPSResourceV2Server.Tests.ps1 b/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 similarity index 99% rename from test/FindPSResourceV2Server.Tests.ps1 rename to test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 index b518cf828..6d479fc95 100644 --- a/test/FindPSResourceV2Server.Tests.ps1 +++ b/test/FindPSResourceTests/FindPSResourceV2Server.Tests.ps1 @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -Import-Module "$psscriptroot\PSGetTestUtils.psm1" -Force +Import-Module "$((Get-Item $psscriptroot).parent)\PSGetTestUtils.psm1" -Force Describe 'Test HTTP Find-PSResource for V2 Server Protocol' { diff --git a/test/FindPSResourceV3Server.Tests.ps1 b/test/FindPSResourceTests/FindPSResourceV3Server.Tests.ps1 similarity index 99% rename from test/FindPSResourceV3Server.Tests.ps1 rename to test/FindPSResourceTests/FindPSResourceV3Server.Tests.ps1 index e3756a5bd..b87768784 100644 --- a/test/FindPSResourceV3Server.Tests.ps1 +++ b/test/FindPSResourceTests/FindPSResourceV3Server.Tests.ps1 @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -Import-Module "$psscriptroot\PSGetTestUtils.psm1" -Force +Import-Module "$((Get-Item $psscriptroot).parent)\PSGetTestUtils.psm1" -Force Describe 'Test HTTP Find-PSResource for V2 Server Protocol' { diff --git a/test/InstallPSResourceTests/InstallPSResource.Tests.ps1 b/test/InstallPSResourceTests/InstallPSResource.Tests.ps1 new file mode 100644 index 000000000..a744d8e4b --- /dev/null +++ b/test/InstallPSResourceTests/InstallPSResource.Tests.ps1 @@ -0,0 +1,562 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +$ProgressPreference = "SilentlyContinue" +Import-Module "$psscriptroot\PSGetTestUtils.psm1" -Force + +Describe 'Test Install-PSResource for Module' { + + BeforeAll { + $PSGalleryName = Get-PSGalleryName + $PSGalleryUri = Get-PSGalleryLocation + $NuGetGalleryName = Get-NuGetGalleryName + $testModuleName = "test_module" + $testModuleName2 = "TestModule99" + $testScriptName = "test_script" + $PackageManagement = "PackageManagement" + $RequiredResourceJSONFileName = "TestRequiredResourceFile.json" + $RequiredResourcePSD1FileName = "TestRequiredResourceFile.psd1" + Get-NewPSResourceRepositoryFile + Register-LocalRepos + } + + AfterEach { + Uninstall-PSResource "test_module", "test_module2", "test_script", "TestModule99", "testModuleWithlicense", "TestFindModule","ClobberTestModule1", "ClobberTestModule2", "PackageManagement" -SkipDependencyCheck -ErrorAction SilentlyContinue + } + + AfterAll { + Get-RevertPSResourceRepositoryFile + } + + $testCases = @{Name="*"; ErrorId="NameContainsWildcard"}, + @{Name="Test_Module*"; ErrorId="NameContainsWildcard"}, + @{Name="Test?Module","Test[Module"; ErrorId="ErrorFilteringNamesForUnsupportedWildcards"} + + It "Should not install resource with wildcard in name" -TestCases $testCases { + param($Name, $ErrorId) + Install-PSResource -Name $Name -ErrorVariable err -ErrorAction SilentlyContinue + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "$ErrorId,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + } + + It "Install specific module resource by name" { + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.0.0" + } + + It "Install specific script resource by name" { + Install-PSResource -Name $testScriptName -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testScriptName + $pkg.Name | Should -Be $testScriptName + $pkg.Version | Should -Be "3.5.0.0" + } + + It "Install multiple resources by name" { + $pkgNames = @($testModuleName,$testModuleName2) + Install-PSResource -Name $pkgNames -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $pkgNames + $pkg.Name | Should -Be $pkgNames + } + + It "Should not install resource given nonexistant name" { + Install-PSResource -Name "NonExistantModule" -Repository $PSGalleryName -TrustRepository -ErrorVariable err -ErrorAction SilentlyContinue + $pkg = Get-PSResource "NonExistantModule" + $pkg.Name | Should -BeNullOrEmpty + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "ResourceNotFoundError,Microsoft.PowerShell.PowerShellGet.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 $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "1.0.0.0" + } + + It "Should install resource given name and exact version with bracket syntax" { + Install-PSResource -Name $testModuleName -Version "[1.0.0]" -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "1.0.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 $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.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 $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "3.0.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 $PSGalleryName -TrustRepository -ErrorAction SilentlyContinue + } + catch + {} + $Error[0].FullyQualifiedErrorId | Should -be "IncorrectVersionFormat,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + + $res = Get-PSResource $testModuleName + $res | Should -BeNullOrEmpty + } + + It "Should not install resource with incorrectly formatted version such as version formatted with invalid delimiter [1-0-0-0]" { + $Version="[1-0-0-0]" + try { + Install-PSResource -Name $testModuleName -Version $Version -Repository $PSGalleryName -TrustRepository -ErrorAction SilentlyContinue + } + catch + {} + $Error[0].FullyQualifiedErrorId | Should -be "ResourceNotFoundError,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + + $res = Get-PSResource $testModuleName + $res | Should -BeNullOrEmpty + } + + It "Install resource when given Name, Version '*', should install the latest version" { + Install-PSResource -Name $testModuleName -Version "*" -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.0.0" + } + + It "Install resource with latest (including prerelease) version given Prerelease parameter" { + Install-PSResource -Name $testModuleName -Prerelease -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.2.5" + $pkg.Prerelease | Should -Be "alpha001" + } + + It "Install a module with a dependency" { + Uninstall-PSResource -Name "TestModuleWithDependency*" -Version "*" -SkipDependencyCheck + Install-PSResource -Name "TestModuleWithDependencyC" -Version "1.0.0.0" -Repository $PSGalleryName -TrustRepository + + $pkg = Get-PSResource "TestModuleWithDependencyC" + $pkg.Name | Should -Be "TestModuleWithDependencyC" + $pkg.Version | Should -Be "1.0.0.0" + + $pkg = Get-PSResource "TestModuleWithDependencyB" + $pkg.Name | Should -Be "TestModuleWithDependencyB" + $pkg.Version | Should -Be "3.0.0.0" + + $pkg = Get-PSResource "TestModuleWithDependencyD" + $pkg.Name | Should -Be "TestModuleWithDependencyD" + $pkg.Version | Should -Be "1.0.0.0" + } + + It "Install a module with a dependency and skip installing the dependency" { + Uninstall-PSResource -Name "TestModuleWithDependency*" -Version "*" -SkipDependencyCheck + Install-PSResource -Name "TestModuleWithDependencyC" -Version "1.0.0.0" -SkipDependencyCheck -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource "TestModuleWithDependencyC" + $pkg.Name | Should -Be "TestModuleWithDependencyC" + $pkg.Version | Should -Be "1.0.0.0" + + $pkg = Get-PSResource "TestModuleWithDependencyB", "TestModuleWithDependencyD" + $pkg | Should -BeNullOrEmpty + } + + It "Install resource via InputObject by piping from Find-PSresource" { + Find-PSResource -Name $testModuleName -Repository $PSGalleryName | Install-PSResource -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.0.0" + } + + It "Install resource under specified in PSModulePath" { + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + ($env:PSModulePath).Contains($pkg.InstalledLocation) + } + + It "Install resource with companyname, copyright and repository source location and validate" { + Install-PSResource -Name $testModuleName -Version "5.2.5-alpha001" -Repository PSGallery -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Version | Should -Be "5.2.5" + $pkg.Prerelease | Should -Be "alpha001" + + $pkg.CompanyName | Should -Be "Anam" + $pkg.Copyright | Should -Be "(c) Anam Navied. All rights reserved." + $pkg.RepositorySourceLocation | Should -Be $PSGalleryUri + } + + + It "Install script with companyname, copyright, and repository source location and validate" { + Install-PSResource -Name "Install-VSCode" -Version "1.4.2" -Repository $PSGalleryName -TrustRepository + + $res = Get-PSResource "Install-VSCode" -Version "1.4.2" + $res.Name | Should -Be "Install-VSCode" + $res.Version | Should -Be "1.4.2.0" + $res.CompanyName | Should -Be "Microsoft Corporation" + $res.Copyright | Should -Be "(c) Microsoft Corporation" + $res.RepositorySourceLocation | Should -Be $PSGalleryUri + } + + # Windows only + It "Install resource under CurrentUser scope - Windows only" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository -Scope CurrentUser + $pkg = Get-PSResource $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 "testmodule99" -Repository $PSGalleryName -TrustRepository -Scope AllUsers -Verbose + $pkg = Get-Module "testmodule99" -ListAvailable + $pkg.Name | Should -Be "testmodule99" + $pkg.Path.ToString().Contains("Program Files") + } + + # Windows only + It "Install resource under no specified scope - Windows only" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $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 $PSGalleryName -TrustRepository -Scope CurrentUser + $pkg = Get-PSResource $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 $PSGalleryName -TrustRepository + $pkg = Get-PSResource $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 $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository -WarningVariable WarningVar -warningaction SilentlyContinue + $WarningVar | Should -Not -BeNullOrEmpty + } + + It "Reinstall resource that is already installed with -Reinstall parameter" { + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.0.0" + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -Reinstall -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.0.0" + } + + It "Restore resource after reinstall fails" { + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository + $pkg = Get-Module $testModuleName -ListAvailable + $pkg.Name | Should -Contain $testModuleName + $pkg.Version | Should -Contain "5.0.0.0" + + $resourcePath = Split-Path -Path $pkg.Path -Parent + $resourceFiles = Get-ChildItem -Path $resourcePath -Recurse + + # Lock resource file to prevent reinstall from succeeding. + $fs = [System.IO.File]::Open($resourceFiles[0].FullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) + try + { + # Reinstall of resource should fail with one of its files locked. + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository -Reinstall -ErrorVariable ev -ErrorAction Silent + $ev.FullyQualifiedErrorId | Should -BeExactly 'InstallPackageFailed,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource' + } + finally + { + $fs.Close() + } + + # Verify that resource module has been restored. + (Get-ChildItem -Path $resourcePath -Recurse).Count | Should -BeExactly $resourceFiles.Count + } + + # It "Install resource that requires accept license with -AcceptLicense flag" { + # Install-PSResource -Name "testModuleWithlicense" -Repository $TestGalleryName -AcceptLicense + # $pkg = Get-PSResource "testModuleWithlicense" + # $pkg.Name | Should -Be "testModuleWithlicense" + # $pkg.Version | Should -Be "0.0.3.0" + # } + + + It "Install resource with cmdlet names from a module already installed (should clobber)" { + Install-PSResource -Name "CLobberTestModule1" -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource "ClobberTestModule1" + $pkg.Name | Should -Be "ClobberTestModule1" + $pkg.Version | Should -Be "0.0.1.0" + + Install-PSResource -Name "ClobberTestModule2" -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource "ClobberTestModule2" + $pkg.Name | Should -Be "ClobberTestModule2" + $pkg.Version | Should -Be "0.0.1.0" + } + + It "Install resource from local repository given Repository parameter" { + $publishModuleName = "TestFindModule" + $repoName = "psgettestlocal" + Get-ModuleResourcePublishedToLocalRepoTestDrive $publishModuleName $repoName + Set-PSResourceRepository "psgettestlocal" -Trusted:$true + + Install-PSResource -Name $publishModuleName -Repository $repoName + $pkg = Get-PSResource $publishModuleName + $pkg | Should -Not -BeNullOrEmpty + $pkg.Name | Should -Be $publishModuleName + } + + It "Install module using -WhatIf, should not install the module" { + Install-PSResource -Name $testModuleName -WhatIf + + $res = Get-PSResource $testModuleName + $res | Should -BeNullOrEmpty + } + + It "Validates that a module with module-name script files (like Pester) installs under Modules path" { + + Install-PSResource -Name "testModuleWithScript" -Repository $PSGalleryName -TrustRepository + + $res = Get-PSResource "testModuleWithScript" + $res.InstalledLocation.ToString().Contains("Modules") | Should -Be $true + } + + It "Install module using -NoClobber, should throw clobber error and not install the module" { + Install-PSResource -Name "ClobberTestModule1" -Repository $PSGalleryName -TrustRepository + + $res = Get-PSResource "ClobberTestModule1" + $res.Name | Should -Be "ClobberTestModule1" + + Install-PSResource -Name "ClobberTestModule2" -Repository $PSGalleryName -TrustRepository -NoClobber -ErrorAction SilentlyContinue + $Error[0].FullyQualifiedErrorId | Should -be "CommandAlreadyExists,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + } + + It "Install PSResourceInfo object piped in" { + Find-PSResource -Name $testModuleName -Version "1.0.0.0" -Repository $PSGalleryName | Install-PSResource -TrustRepository + $res = Get-PSResource -Name $testModuleName + $res.Name | Should -Be $testModuleName + $res.Version | Should -Be "1.0.0.0" + } + + It "Install module using -PassThru" { + $res = Install-PSResource -Name $testModuleName -Repository $PSGalleryName -PassThru -TrustRepository + $res.Name | Should -Contain $testModuleName + } + + It "Install modules using -RequiredResource with hashtable" { + $rrHash = @{ + test_module = @{ + version = "[1.0.0,5.0.0)" + repository = $PSGalleryName + } + + test_module2 = @{ + version = "[1.0.0,3.0.0)" + repository = $PSGalleryName + prerelease = "true" + } + + TestModule99 = @{} + } + + Install-PSResource -RequiredResource $rrHash -TrustRepository + + $res1 = Get-PSResource $testModuleName + $res1.Name | Should -Be $testModuleName + $res1.Version | Should -Be "3.0.0.0" + + $res2 = Get-PSResource "test_module2" -Version "2.5.0-beta" + $res2.Name | Should -Be "test_module2" + $res2.Version | Should -Be "2.5.0" + $res2.Prerelease | Should -Be "beta" + + $res3 = Get-PSResource $testModuleName2 + $res3.Name | Should -Be $testModuleName2 + $res3.Version | Should -Be "0.0.93.0" + } + + It "Install modules using -RequiredResource with JSON string" { + $rrJSON = "{ + 'test_module': { + 'version': '[1.0.0,5.0.0)', + 'repository': 'PSGallery' + }, + 'test_module2': { + 'version': '[1.0.0,3.0.0)', + 'repository': 'PSGallery', + 'prerelease': 'true' + }, + 'TestModule99': { + 'repository': 'PSGallery' + } + }" + + Install-PSResource -RequiredResource $rrJSON -TrustRepository + + $res1 = Get-PSResource $testModuleName + $res1.Name | Should -Be $testModuleName + $res1.Version | Should -Be "3.0.0.0" + + $res2 = Get-PSResource "test_module2" -Version "2.5.0-beta" + $res2.Name | Should -Be "test_module2" + $res2.Version | Should -Be "2.5.0" + $res2.Prerelease | Should -Be "beta" + + $res3 = Get-PSResource $testModuleName2 + $res3.Name | Should -Be $testModuleName2 + $res3.Version | Should -Be "0.0.93.0" + } + + It "Install modules using -RequiredResourceFile with PSD1 file" { + $rrFilePSD1 = Join-Path -Path $psscriptroot -ChildPath $RequiredResourcePSD1FileName + + Install-PSResource -RequiredResourceFile $rrFilePSD1 -TrustRepository + + $res1 = Get-PSResource $testModuleName + $res1.Name | Should -Be $testModuleName + $res1.Version | Should -Be "3.0.0.0" + + $res2 = Get-PSResource "test_module2" -Version "2.5.0-beta" + $res2.Name | Should -Be "test_module2" + $res2.Version | Should -Be "2.5.0" + $res2.Prerelease | Should -Be "beta" + + $res3 = Get-PSResource $testModuleName2 + $res3.Name | Should -Be $testModuleName2 + $res3.Version | Should -Be "0.0.93.0" + } + + It "Install modules using -RequiredResourceFile with JSON file" { + $rrFileJSON = Join-Path -Path $psscriptroot -ChildPath $RequiredResourceJSONFileName + + Install-PSResource -RequiredResourceFile $rrFileJSON -TrustRepository + + $res1 = Get-PSResource $testModuleName + $res1.Name | Should -Be $testModuleName + $res1.Version | Should -Be "3.0.0.0" + + $res2 = Get-PSResource "test_module2" -Version "2.5.0-beta" + $res2.Name | Should -Be "test_module2" + $res2.Version | Should -Be "2.5.0" + $res2.Prerelease | Should -Be "beta" + + $res3 = Get-PSResource $testModuleName2 + $res3.Name | Should -Be $testModuleName2 + $res3.Version | Should -Be "0.0.93.0" + } + + # Install module 1.4.3 (is authenticode signed and has catalog file) + # Should install successfully + It "Install modules with catalog file using publisher validation" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name $PackageManagement -Version "1.4.3" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository + + $res1 = Get-PSResource $PackageManagement -Version "1.4.3" + $res1.Name | Should -Be $PackageManagement + $res1.Version | Should -Be "1.4.3.0" + } + + # Install module 1.4.7 (is authenticode signed and has no catalog file) + # Should not install successfully + It "Install module with no catalog file" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name $PackageManagement -Version "1.4.7" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository + + $res1 = Get-PSResource $PackageManagement -Version "1.4.7" + $res1.Name | Should -Be $PackageManagement + $res1.Version | Should -Be "1.4.7.0" + } + + # Install module that is not authenticode signed + # Should FAIL to install the module + It "Install module that is not authenticode signed" -Skip:(!(Get-IsWindows)) { + { Install-PSResource -Name $testModuleName -Version "5.0.0" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository } | Should -Throw -ErrorId "GetAuthenticodeSignatureError,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + } + + # Install 1.4.4.1 (with incorrect catalog file) + # Should FAIL to install the module + It "Install module with incorrect catalog file" -Skip:(!(Get-IsWindows)) { + { Install-PSResource -Name $PackageManagement -Version "1.4.4.1" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository } | Should -Throw -ErrorId "TestFileCatalogError,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + } + + # Install script that is signed + # Should install successfully + It "Install script that is authenticode signed" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name "Install-VSCode" -Version "1.4.2" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository + + $res1 = Get-PSResource "Install-VSCode" -Version "1.4.2" + $res1.Name | Should -Be "Install-VSCode" + $res1.Version | Should -Be "1.4.2.0" + } + + # Install script that is not signed + # Should throw + It "Install script that is not signed" -Skip:(!(Get-IsWindows)) { + { Install-PSResource -Name "TestTestScript" -Version "1.3.1.1" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository } | Should -Throw -ErrorId "GetAuthenticodeSignatureError,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + } +} + +<# Temporarily commented until -Tag is implemented for this Describe block +Describe 'Test Install-PSResource for interactive and root user scenarios' { + + BeforeAll{ + $TestGalleryName = Get-PoshTestGalleryName + $PSGalleryName = Get-PSGalleryName + $NuGetGalleryName = Get-NuGetGalleryName + Get-NewPSResourceRepositoryFile + Register-LocalRepos + } + + AfterEach { + Uninstall-PSResource "TestModule", "testModuleWithlicense" -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 "TestModule" -Repository $TestGalleryName -Scope AllUsers + $pkg = Get-Module "TestModule" -ListAvailable + $pkg.Name | Should -Be "TestModule" + $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 "testModuleWithlicense" -Repository $TestGalleryName + $pkg = Get-PSResource "testModuleWithlicense" + $pkg.Name | Should -Be "testModuleWithlicense" + $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 "TestModule" -Repository $TestGalleryName -confirm:$false + + $pkg = Get-Module "TestModule" -ListAvailable + $pkg.Name | Should -Be "TestModule" + + Set-PSResourceRepository PoshTestGallery -Trusted + } +} +#> diff --git a/test/InstallPSResourceTests/InstallPSResourceLocal.Tests.ps1 b/test/InstallPSResourceTests/InstallPSResourceLocal.Tests.ps1 new file mode 100644 index 000000000..cda98947c --- /dev/null +++ b/test/InstallPSResourceTests/InstallPSResourceLocal.Tests.ps1 @@ -0,0 +1,275 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +$ProgressPreference = "SilentlyContinue" +Import-Module "$((Get-Item $psscriptroot).parent)\PSGetTestUtils.psm1" -Force + +Describe 'Test Install-PSResource for local repositories' { + + + BeforeAll { + $localRepo = "psgettestlocal" + $moduleName = "test_local_mod" + $moduleName2 = "test_local_mod2" + Get-NewPSResourceRepositoryFile + Register-LocalRepos + + Get-ModuleResourcePublishedToLocalRepoTestDrive $moduleName $localRepo "1.0.0" + Get-ModuleResourcePublishedToLocalRepoTestDrive $moduleName $localRepo "3.0.0" + Get-ModuleResourcePublishedToLocalRepoTestDrive $moduleName $localRepo "5.0.0" + Get-ModuleResourcePublishedToLocalRepoTestDrive $moduleName2 $localRepo "1.0.0" + Get-ModuleResourcePublishedToLocalRepoTestDrive $moduleName2 $localRepo "5.0.0" + } + + AfterEach { + Uninstall-PSResource $moduleName, $moduleName2 -Version "*" + } + + AfterAll { + Get-RevertPSResourceRepositoryFile + } + + It "Update resource installed given Name parameter" { + Install-PSResource -Name $moduleName -Version "1.0.0" -Repository $localRepo -TrustRepository + + Update-PSResource -Name $moduleName -Repository $localRepo -TrustRepository + $res = Get-PSResource -Name $moduleName + + $isPkgUpdated = $false + foreach ($pkg in $res) + { + if ([System.Version]$pkg.Version -gt [System.Version]"1.0.0") + { + $isPkgUpdated = $true + } + } + + $isPkgUpdated | Should -Be $true + } + + It "Update resources installed given Name (with wildcard) parameter" { + Install-PSResource -Name $moduleName -Version "1.0.0" -Repository $localRepo -TrustRepository + Install-PSResource -Name $moduleName2 -Version "1.0.0" -Repository $localRepo -TrustRepository + + Update-PSResource -Name "test_local*" -Repository $localRepo -TrustRepository + $res = Get-PSResource -Name "test_local*" -Version "5.0.0" + + $inputHashtable = @{test_module = "1.0.0"; test_module2 = "1.0.0"} + $isTest_ModuleUpdated = $false + $isTest_Module2Updated = $false + foreach ($item in $res) + { + if ([System.Version]$item.Version -gt [System.Version]$inputHashtable[$item.Name]) + { + if ($item.Name -like $moduleName) + { + $isTest_ModuleUpdated = $true + } + elseif ($item.Name -like $moduleName2) + { + $isTest_Module2Updated = $true + } + } + } + + $isTest_ModuleUpdated | Should -BeTrue + $isTest_Module2Updated | Should -BeTrue + } + + It "Update resource installed given Name and Version (specific) parameters" { + Install-PSResource -Name $moduleName -Version "1.0.0" -Repository $localRepo -TrustRepository + + Update-PSResource -Name $moduleName -Version "5.0.0" -Repository $localRepo -TrustRepository + $res = Get-PSResource -Name $moduleName + $isPkgUpdated = $false + foreach ($pkg in $res) + { + if ([System.Version]$pkg.Version -eq [System.Version]"5.0.0.0") + { + $isPkgUpdated = $true + } + } + + $isPkgUpdated | Should -BeTrue + } + + # Windows only + It "update resource under CurrentUser scope" -skip:(!($IsWindows -and (Test-IsAdmin))) { + # TODO: perhaps also install TestModule with the highest version (the one above 1.2.0.0) to the AllUsers path too + Install-PSResource -Name $moduleName -Version "1.0.0.0" -Repository $localRepo -TrustRepository -Scope AllUsers + Install-PSResource -Name $moduleName -Version "1.0.0.0" -Repository $localRepo -TrustRepository -Scope CurrentUser + + Update-PSResource -Name $moduleName -Version "3.0.0.0" -Repository $localRepo -TrustRepository -Scope CurrentUser + + $res = Get-PSResource -Name $moduleName + + $isPkgUpdated = $false + foreach ($pkg in $res) + { + if ([System.Version]$pkg.Version -gt [System.Version]"1.0.0.0") + { + $pkg.InstalledLocation.Contains("Documents") | Should -Be $true + $isPkgUpdated = $true + } + } + + $isPkgUpdated | Should -Be $true + } + + # Windows only + It "update resource under AllUsers scope" -skip:(!($IsWindows -and (Test-IsAdmin))) { + Install-PSResource -Name $moduleName -Version "1.0.0" -Repository $localRepo -TrustRepository -Scope AllUsers + + Update-PSResource -Name $moduleName -Repository $localRepo -TrustRepository -Scope AllUsers + + $res = Get-Module -Name $moduleName -ListAvailable + $res | Should -Not -BeNullOrEmpty + $res.Version | Should -Contain "5.0.0" + + $isPkgUpdated = $false + foreach ($pkg in $res) + { + if ([System.Version]$pkg.Version -gt [System.Version]"1.0.0.0") + { + $pkg.ModuleBase.Contains("Program") | Should -Be $true + $isPkgUpdated = $true + } + } + $isPkgUpdated | Should -Be $true + + } + + # Windows only + It "Update resource under no specified scope" -skip:(!$IsWindows) { + Install-PSResource -Name $moduleName -Version "1.0.0.0" -Repository $localRepo -TrustRepository + Update-PSResource -Name $moduleName -Version "5.0.0.0" -Repository $localRepo -TrustRepository + + $res = Get-PSResource -Name $moduleName + + $isPkgUpdated = $false + foreach ($pkg in $res) + { + if ([System.Version]$pkg.Version -gt [System.Version]"1.0.0.0") + { + $pkg.InstalledLocation.Contains("Documents") | Should -Be $true + $isPkgUpdated = $true + } + } + + $isPkgUpdated | Should -Be $true + } + + # Unix only + # Expected path should be similar to: '/home/janelane/.local/share/powershell/Modules' + It "Update resource under CurrentUser scope - Unix only" -Skip:(Get-IsWindows) { + # this line is commented out because AllUsers scope requires sudo and that isn't supported in CI yet + # Install-PSResource -Name "TestModule" -Version "1.1.0.0" -Repository $TestGalleryName -Scope AllUsers + Install-PSResource -Name $moduleName -Version "1.0.0.0" -Repository $localRepo -TrustRepository -Scope CurrentUser + + Update-PSResource -Name $moduleName -Repository $localRepo -TrustRepository -Scope CurrentUser + + $res = Get-PSResource -Name $moduleName + + $isPkgUpdated = $false + foreach ($pkg in $res) + { + if ([System.Version]$pkg.Version -gt [System.Version]"1.0.0.0") + { + $pkg.InstalledLocation.Contains("$env:HOME/.local") | Should -Be $true + $isPkgUpdated = $true + } + } + + $isPkgUpdated | Should -Be $true + } + + # Unix only + # Expected path should be similar to: '/usr/local/share/powershell/Modules' + # this test is skipped because it requires sudo to run and has yet to be resolved in CI + It "Update resource under AllUsers scope - Unix only" -Skip:($true) { + Install-PSResource -Name $moduleName -Version "1.0.0.0" -Repository $localRepo -TrustRepository -Scope AllUsers + + Update-PSResource -Name $moduleName -Repository $PSGalleryName -TrustRepository -Scope AllUsers + + $res = Get-PSResource -Name $moduleName + + $isPkgUpdated = $false + foreach ($pkg in $res) + { + if ([System.Version]$pkg.Version -gt [System.Version]"1.0.0.0") + { + $pkg.InstalledLocation.Contains("usr") | Should -Be $true + $isPkgUpdated = $true + } + } + + $isPkgUpdated | Should -Be $true + } + + # Unix only + # Expected path should be similar to: '/home/janelane/.local/share/powershell/Modules' + It "Update resource under no specified scope - Unix only" -Skip:(Get-IsWindows) { + # this is commented out because it requires sudo to run with AllUsers scope and this hasn't been resolved in CI yet + # Install-PSResource -Name "TestModule" -Version "1.1.0.0" -Repository $TestGalleryName -Scope AllUsers + Install-PSResource -Name $moduleName -Version "1.0.0.0" -Repository $localRepo -TrustRepository -Scope CurrentUser + + Update-PSResource -Name $moduleName -Repository $localRepo -TrustRepository + + $res = Get-PSResource -Name $moduleName + + $isPkgUpdated = $false + foreach ($pkg in $res) + { + if ([System.Version]$pkg.Version -gt [System.Version]"1.0.0.0") + { + $pkg.InstalledLocation.Contains("$env:HOME/.local") | Should -Be $true + $isPkgUpdated = $true + } + } + + $isPkgUpdated | Should -Be $true + } + + # It "update resource that requires accept license with -AcceptLicense flag" { + # Install-PSResource -Name "TestModuleWithLicense" -Version "0.0.1.0" -Repository $TestGalleryName -AcceptLicense + # Update-PSResource -Name "TestModuleWithLicense" -Repository $TestGalleryName -AcceptLicense + # $res = Get-PSResource "TestModuleWithLicense" + + # $isPkgUpdated = $false + # foreach ($pkg in $res) + # { + # if ([System.Version]$pkg.Version -gt [System.Version]"0.0.1.0") + # { + # $isPkgUpdated = $true + # } + # } + + # $isPkgUpdated | Should -Be $true + # } + + It "Update module using -WhatIf, should not update the module" { + Install-PSResource -Name $moduleName -Version "1.0.0.0" -Repository $localRepo -TrustRepository + Update-PSResource -Name $moduleName -WhatIf -Repository $localRepo -TrustRepository + + $res = Get-PSResource -Name $moduleName + + $isPkgUpdated = $false + foreach ($pkg in $res) + { + if ([System.Version]$pkg.Version -gt [System.Version]"1.0.0.0") + { + $isPkgUpdated = $true + } + } + + $isPkgUpdated | Should -Be $false + } + + It "Update resource installed given -Name and -PassThru parameters" { + Install-PSResource -Name $moduleName -Version "1.0.0.0" -Repository $localRepo -TrustRepository + + $res = Update-PSResource -Name $moduleName -Version "5.0.0.0" -Repository $localRepo -TrustRepository -PassThru + $res.Name | Should -Contain $moduleName + $res.Version | Should -Be "5.0.0.0" + } +} diff --git a/test/InstallPSResourceTests/InstallPSResourceV2Server.Tests.ps1 b/test/InstallPSResourceTests/InstallPSResourceV2Server.Tests.ps1 new file mode 100644 index 000000000..9a83695eb --- /dev/null +++ b/test/InstallPSResourceTests/InstallPSResourceV2Server.Tests.ps1 @@ -0,0 +1,543 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +$ProgressPreference = "SilentlyContinue" +Import-Module "$((Get-Item $psscriptroot).parent)\PSGetTestUtils.psm1" -Force + +Describe 'Test Install-PSResource for V2 Server scenarios' { + + BeforeAll { + $PSGalleryName = Get-PSGalleryName + $PSGalleryUri = Get-PSGalleryLocation + $NuGetGalleryName = Get-NuGetGalleryName + $testModuleName = "test_module" + $testModuleName2 = "TestModule99" + $testScriptName = "test_script" + $PackageManagement = "PackageManagement" + $RequiredResourceJSONFileName = "TestRequiredResourceFile.json" + $RequiredResourcePSD1FileName = "TestRequiredResourceFile.psd1" + Get-NewPSResourceRepositoryFile + Register-LocalRepos + } + + AfterEach { + Uninstall-PSResource "test_module", "test_module2", "test_script", "TestModule99", "testModuleWithlicense", "TestFindModule","ClobberTestModule1", "ClobberTestModule2", "PackageManagement" -SkipDependencyCheck -ErrorAction SilentlyContinue + } + + AfterAll { + Get-RevertPSResourceRepositoryFile + } + + $testCases = @{Name="*"; ErrorId="NameContainsWildcard"}, + @{Name="Test_Module*"; ErrorId="NameContainsWildcard"}, + @{Name="Test?Module","Test[Module"; ErrorId="ErrorFilteringNamesForUnsupportedWildcards"} + + It "Should not install resource with wildcard in name" -TestCases $testCases { + param($Name, $ErrorId) + Install-PSResource -Name $Name -Repository $PSGalleryName -ErrorVariable err -ErrorAction SilentlyContinue + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "$ErrorId,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + } + + It "Install specific module resource by name" { + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.0.0" + } + + It "Install specific script resource by name" { + Install-PSResource -Name $testScriptName -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testScriptName + $pkg.Name | Should -Be $testScriptName + $pkg.Version | Should -Be "3.5.0.0" + } + + It "Install multiple resources by name" { + $pkgNames = @($testModuleName, $testModuleName2) + Install-PSResource -Name $pkgNames -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $pkgNames + $pkg.Name | Should -Be $pkgNames + } + + It "Should not install resource given nonexistant name" { + Install-PSResource -Name "NonExistantModule" -Repository $PSGalleryName -TrustRepository -ErrorVariable err -ErrorAction SilentlyContinue + $pkg = Get-PSResource "NonExistantModule" + $pkg.Name | Should -BeNullOrEmpty + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "InstallPackageFailure,Microsoft.PowerShell.PowerShellGet.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 $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "1.0.0.0" + } + + It "Should install resource given name and exact version with bracket syntax" { + Install-PSResource -Name $testModuleName -Version "[1.0.0]" -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "1.0.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 $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.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 $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "3.0.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 $PSGalleryName -TrustRepository -ErrorAction SilentlyContinue + } + catch + {} + $Error[0].FullyQualifiedErrorId | Should -be "IncorrectVersionFormat,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + + $res = Get-PSResource $testModuleName + $res | Should -BeNullOrEmpty + } + + It "Install resource when given Name, Version '*', should install the latest version" { + Install-PSResource -Name $testModuleName -Version "*" -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.0.0" + } + + It "Install resource with latest (including prerelease) version given Prerelease parameter" { + Install-PSResource -Name $testModuleName -Prerelease -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.2.5" + $pkg.Prerelease | Should -Be "alpha001" + } + + It "Install a module with a dependency" { + Uninstall-PSResource -Name "TestModuleWithDependency*" -Version "*" -SkipDependencyCheck + Install-PSResource -Name "TestModuleWithDependencyC" -Version "1.0.0.0" -Repository $PSGalleryName -TrustRepository + + $pkg = Get-PSResource "TestModuleWithDependencyC" + $pkg.Name | Should -Be "TestModuleWithDependencyC" + $pkg.Version | Should -Be "1.0" + + $pkg = Get-PSResource "TestModuleWithDependencyB" + $pkg.Name | Should -Be "TestModuleWithDependencyB" + $pkg.Version | Should -Be "3.0" + + $pkg = Get-PSResource "TestModuleWithDependencyD" + $pkg.Name | Should -Be "TestModuleWithDependencyD" + $pkg.Version | Should -Be "1.0" + } + + It "Install a module with a dependency and skip installing the dependency" { + Uninstall-PSResource -Name "TestModuleWithDependency*" -Version "*" -SkipDependencyCheck + Install-PSResource -Name "TestModuleWithDependencyC" -Version "1.0.0.0" -SkipDependencyCheck -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource "TestModuleWithDependencyC" + $pkg.Name | Should -Be "TestModuleWithDependencyC" + $pkg.Version | Should -Be "1.0" + + $pkg = Get-PSResource "TestModuleWithDependencyB", "TestModuleWithDependencyD" + $pkg | Should -BeNullOrEmpty + } + + It "Install resource via InputObject by piping from Find-PSresource" { + Find-PSResource -Name $testModuleName -Repository $PSGalleryName | Install-PSResource -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.0.0" + } + + It "Install resource under specified in PSModulePath" { + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + ($env:PSModulePath).Contains($pkg.InstalledLocation) + } + + It "Install resource with companyname, copyright and repository source location and validate" { + Install-PSResource -Name $testModuleName -Version "5.2.5-alpha001" -Repository PSGallery -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Version | Should -Be "5.2.5" + $pkg.Prerelease | Should -Be "alpha001" + + $pkg.CompanyName | Should -Be "Anam" + $pkg.Copyright | Should -Be "(c) Anam Navied. All rights reserved." + $pkg.RepositorySourceLocation | Should -Be $PSGalleryUri + } + + + It "Install script with companyname, copyright, and repository source location and validate" { + Install-PSResource -Name "Install-VSCode" -Version "1.4.2" -Repository $PSGalleryName -TrustRepository + + $res = Get-PSResource "Install-VSCode" -Version "1.4.2" + $res.Name | Should -Be "Install-VSCode" + $res.Version | Should -Be "1.4.2" + $res.CompanyName | Should -Be "Microsoft Corporation" + $res.Copyright | Should -Be "(c) Microsoft Corporation" + $res.RepositorySourceLocation | Should -Be $PSGalleryUri + } + + # Windows only + It "Install resource under CurrentUser scope - Windows only" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository -Scope CurrentUser + $pkg = Get-PSResource $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 "testmodule99" -Repository $PSGalleryName -TrustRepository -Scope AllUsers -Verbose + $pkg = Get-Module "testmodule99" -ListAvailable + $pkg.Name | Should -Be "testmodule99" + $pkg.Path.ToString().Contains("Program Files") + } + + # Windows only + It "Install resource under no specified scope - Windows only" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $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 $PSGalleryName -TrustRepository -Scope CurrentUser + $pkg = Get-PSResource $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 $PSGalleryName -TrustRepository + $pkg = Get-PSResource $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 $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository -WarningVariable WarningVar -warningaction SilentlyContinue + $WarningVar | Should -Not -BeNullOrEmpty + } + + It "Reinstall resource that is already installed with -Reinstall parameter" { + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.0.0" + Install-PSResource -Name $testModuleName -Repository $PSGalleryName -Reinstall -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.0.0" + } + + # It "Restore resource after reinstall fails" { + # Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository + # $pkg = Get-PSResource $testModuleName + # $pkg.Name | Should -Contain $testModuleName + # $pkg.Version | Should -Contain "5.0.0.0" + + # $resourcePath = Split-Path -Path $pkg.InstalledLocation -Parent + # $resourceFiles = Get-ChildItem -Path $resourcePath -Recurse + + # # Lock resource file to prevent reinstall from succeeding. + # $fs = [System.IO.File]::Open($resourceFiles[0].FullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) + # try + # { + # # Reinstall of resource should fail with one of its files locked. + # Install-PSResource -Name $testModuleName -Repository $PSGalleryName -TrustRepository -Reinstall -ErrorVariable ev -ErrorAction Silent + # $ev.FullyQualifiedErrorId | Should -BeExactly 'InstallPackageFailed,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource' + # } + # finally + # { + # $fs.Close() + # } + + # # Verify that resource module has been restored. + # (Get-ChildItem -Path $resourcePath -Recurse).Count | Should -BeExactly $resourceFiles.Count + # } + + # It "Install resource that requires accept license with -AcceptLicense flag" { + # Install-PSResource -Name "testModuleWithlicense" -Repository $TestGalleryName -AcceptLicense + # $pkg = Get-PSResource "testModuleWithlicense" + # $pkg.Name | Should -Be "testModuleWithlicense" + # $pkg.Version | Should -Be "0.0.3.0" + # } + + + It "Install resource with cmdlet names from a module already installed (should clobber)" { + Install-PSResource -Name "CLobberTestModule1" -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource "ClobberTestModule1" + $pkg.Name | Should -Be "ClobberTestModule1" + $pkg.Version | Should -Be "0.0.1" + + Install-PSResource -Name "ClobberTestModule2" -Repository $PSGalleryName -TrustRepository + $pkg = Get-PSResource "ClobberTestModule2" + $pkg.Name | Should -Be "ClobberTestModule2" + $pkg.Version | Should -Be "0.0.1" + } + + It "Install module using -WhatIf, should not install the module" { + Install-PSResource -Name $testModuleName -WhatIf + + $res = Get-PSResource $testModuleName + $res | Should -BeNullOrEmpty + } + + It "Validates that a module with module-name script files (like Pester) installs under Modules path" { + + Install-PSResource -Name "testModuleWithScript" -Repository $PSGalleryName -TrustRepository + + $res = Get-PSResource "testModuleWithScript" + $res.InstalledLocation.ToString().Contains("Modules") | Should -Be $true + } + + # It "Install module using -NoClobber, should throw clobber error and not install the module" { + # Install-PSResource -Name "ClobberTestModule1" -Repository $PSGalleryName -TrustRepository + + # $res = Get-PSResource "ClobberTestModule1" + # $res.Name | Should -Be "ClobberTestModule1" + + # Install-PSResource -Name "ClobberTestModule2" -Repository $PSGalleryName -TrustRepository -NoClobber -ErrorAction SilentlyContinue + # $Error[0].FullyQualifiedErrorId | Should -be "CommandAlreadyExists,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + # } + + It "Install PSResourceInfo object piped in" { + Find-PSResource -Name $testModuleName -Version "1.0.0.0" -Repository $PSGalleryName | Install-PSResource -TrustRepository + $res = Get-PSResource -Name $testModuleName + $res.Name | Should -Be $testModuleName + $res.Version | Should -Be "1.0.0.0" + } + + It "Install module using -PassThru" { + $res = Install-PSResource -Name $testModuleName -Repository $PSGalleryName -PassThru -TrustRepository + $res.Name | Should -Contain $testModuleName + } + + It "Install modules using -RequiredResource with hashtable" { + $rrHash = @{ + test_module = @{ + version = "[1.0.0,5.0.0)" + repository = $PSGalleryName + } + + test_module2 = @{ + version = "[1.0.0,3.0.0)" + repository = $PSGalleryName + prerelease = "true" + } + + TestModule99 = @{ + repository = $PSGalleryName + } + } + + Install-PSResource -RequiredResource $rrHash -TrustRepository + + $res1 = Get-PSResource $testModuleName + $res1.Name | Should -Be $testModuleName + $res1.Version | Should -Be "3.0.0.0" + + $res2 = Get-PSResource "test_module2" -Version "2.5.0-beta" + $res2.Name | Should -Be "test_module2" + $res2.Version | Should -Be "2.5.0" + $res2.Prerelease | Should -Be "beta" + + $res3 = Get-PSResource $testModuleName2 + $res3.Name | Should -Be $testModuleName2 + $res3.Version | Should -Be "0.0.93" + } + + It "Install modules using -RequiredResource with JSON string" { + $rrJSON = "{ + 'test_module': { + 'version': '[1.0.0,5.0.0)', + 'repository': 'PSGallery' + }, + 'test_module2': { + 'version': '[1.0.0,3.0.0)', + 'repository': 'PSGallery', + 'prerelease': 'true' + }, + 'TestModule99': { + 'repository': 'PSGallery' + } + }" + + Install-PSResource -RequiredResource $rrJSON -TrustRepository + + $res1 = Get-PSResource $testModuleName + $res1.Name | Should -Be $testModuleName + $res1.Version | Should -Be "3.0.0.0" + + $res2 = Get-PSResource "test_module2" -Version "2.5.0-beta" + $res2.Name | Should -Be "test_module2" + $res2.Version | Should -Be "2.5.0" + $res2.Prerelease | Should -Be "beta" + + $res3 = Get-PSResource $testModuleName2 + $res3.Name | Should -Be $testModuleName2 + $res3.Version | Should -Be "0.0.93" + } + + It "Install modules using -RequiredResourceFile with PSD1 file" { + $rrFilePSD1 = Join-Path -Path "$((Get-Item $psscriptroot).parent)" -ChildPath $RequiredResourcePSD1FileName + + Install-PSResource -RequiredResourceFile $rrFilePSD1 -TrustRepository + + $res1 = Get-PSResource $testModuleName + $res1.Name | Should -Be $testModuleName + $res1.Version | Should -Be "3.0.0.0" + + $res2 = Get-PSResource "test_module2" -Version "2.5.0-beta" + $res2.Name | Should -Be "test_module2" + $res2.Version | Should -Be "2.5.0" + $res2.Prerelease | Should -Be "beta" + + $res3 = Get-PSResource $testModuleName2 + $res3.Name | Should -Be $testModuleName2 + $res3.Version | Should -Be "0.0.93" + } + + It "Install modules using -RequiredResourceFile with JSON file" { + $rrFileJSON = Join-Path -Path "$((Get-Item $psscriptroot).parent)" -ChildPath $RequiredResourceJSONFileName + + Install-PSResource -RequiredResourceFile $rrFileJSON -TrustRepository + + $res1 = Get-PSResource $testModuleName + $res1.Name | Should -Be $testModuleName + $res1.Version | Should -Be "3.0.0.0" + + $res2 = Get-PSResource "test_module2" -Version "2.5.0-beta" + $res2.Name | Should -Be "test_module2" + $res2.Version | Should -Be "2.5.0" + $res2.Prerelease | Should -Be "beta" + + $res3 = Get-PSResource $testModuleName2 + $res3.Name | Should -Be $testModuleName2 + $res3.Version | Should -Be "0.0.93" + } + + # Install module 1.4.3 (is authenticode signed and has catalog file) + # Should install successfully + It "Install modules with catalog file using publisher validation" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name $PackageManagement -Version "1.4.3" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository + + $res1 = Get-PSResource $PackageManagement -Version "1.4.3" + $res1.Name | Should -Be $PackageManagement + $res1.Version | Should -Be "1.4.3" + } + + # Install module 1.4.7 (is authenticode signed and has no catalog file) + # Should not install successfully + It "Install module with no catalog file" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name $PackageManagement -Version "1.4.7" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository + + $res1 = Get-PSResource $PackageManagement -Version "1.4.7" + $res1.Name | Should -Be $PackageManagement + $res1.Version | Should -Be "1.4.7" + } + + # Install module that is not authenticode signed + # Should FAIL to install the module + It "Install module that is not authenticode signed" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name $testModuleName -Version "5.0.0" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository -ErrorVariable err -ErrorAction SilentlyContinue + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "InstallPackageFailure,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + } + + # # Install 1.4.4.1 (with incorrect catalog file) + # # Should FAIL to install the module + # It "Install module with incorrect catalog file" -Skip:(!(Get-IsWindows)) { + # { Install-PSResource -Name $PackageManagement -Version "1.4.4.1" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository } | Should -Throw -ErrorId "TestFileCatalogError,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + # } + + # Install script that is signed + # Should install successfully + It "Install script that is authenticode signed" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name "Install-VSCode" -Version "1.4.2" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository + + $res1 = Get-PSResource "Install-VSCode" -Version "1.4.2" + $res1.Name | Should -Be "Install-VSCode" + $res1.Version | Should -Be "1.4.2" + } + + # Install script that is not signed + # Should throw + It "Install script that is not signed" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name "TestTestScript" -Version "1.3.1.1" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository -ErrorVariable err -ErrorAction SilentlyContinue + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "InstallPackageFailure,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + } +} + +<# Temporarily commented until -Tag is implemented for this Describe block +Describe 'Test Install-PSResource for interactive and root user scenarios' { + + BeforeAll{ + $TestGalleryName = Get-PoshTestGalleryName + $PSGalleryName = Get-PSGalleryName + $NuGetGalleryName = Get-NuGetGalleryName + Get-NewPSResourceRepositoryFile + Register-LocalRepos + } + + AfterEach { + Uninstall-PSResource "TestModule", "testModuleWithlicense" -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 "TestModule" -Repository $TestGalleryName -Scope AllUsers + $pkg = Get-Module "TestModule" -ListAvailable + $pkg.Name | Should -Be "TestModule" + $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 "testModuleWithlicense" -Repository $TestGalleryName + $pkg = Get-PSResource "testModuleWithlicense" + $pkg.Name | Should -Be "testModuleWithlicense" + $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 "TestModule" -Repository $TestGalleryName -confirm:$false + + $pkg = Get-Module "TestModule" -ListAvailable + $pkg.Name | Should -Be "TestModule" + + Set-PSResourceRepository PoshTestGallery -Trusted + } +} +#> diff --git a/test/InstallPSResourceTests/InstallPSResourceV3Server.Tests.ps1 b/test/InstallPSResourceTests/InstallPSResourceV3Server.Tests.ps1 new file mode 100644 index 000000000..2bd9b3b8d --- /dev/null +++ b/test/InstallPSResourceTests/InstallPSResourceV3Server.Tests.ps1 @@ -0,0 +1,410 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +$ProgressPreference = "SilentlyContinue" +Import-Module "$((Get-Item $psscriptroot).parent)\PSGetTestUtils.psm1" -Force + +Describe 'Test Install-PSResource for V3Server scenarios' { + + BeforeAll { + $NuGetGalleryName = Get-NuGetGalleryName + $NuGetGalleryUri = Get-NuGetGalleryLocation + $testModuleName = "test_module" + $testModuleName2 = "test_module2" + # $testModuleName2 = "TestModule99" + $testScriptName = "test_script" + $PackageManagement = "PackageManagement" + $RequiredResourceJSONFileName = "TestRequiredResourceFile.json" + $RequiredResourcePSD1FileName = "TestRequiredResourceFile.psd1" + Get-NewPSResourceRepositoryFile + Register-LocalRepos + } + + AfterEach { + Uninstall-PSResource "test_module", "test_module2", "test_script", "TestModule99", "testModuleWithlicense", "TestFindModule", "PackageManagement" -SkipDependencyCheck -ErrorAction SilentlyContinue + } + + AfterAll { + Get-RevertPSResourceRepositoryFile + } + + $testCases = @{Name="*"; ErrorId="NameContainsWildcard"}, + @{Name="Test_Module*"; ErrorId="NameContainsWildcard"}, + @{Name="Test?Module","Test[Module"; ErrorId="ErrorFilteringNamesForUnsupportedWildcards"} + + It "Should not install resource with wildcard in name" -TestCases $testCases { + param($Name, $ErrorId) + Install-PSResource -Name $Name -Repository $NuGetGalleryName -ErrorVariable err -ErrorAction SilentlyContinue + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "$ErrorId,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + } + + It "Install specific module resource by name" { + Install-PSResource -Name $testModuleName -Repository $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $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 $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $testScriptName + $pkg.Name | Should -Be $testScriptName + $pkg.Version | Should -Be "3.5.0" + } + + It "Install multiple resources by name" { + $pkgNames = @($testModuleName, $testModuleName2) + Install-PSResource -Name $pkgNames -Repository $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $pkgNames + $pkg.Name | Should -Be $pkgNames + } + + It "Should not install resource given nonexistant name" { + Install-PSResource -Name "NonExistantModule" -Repository $NuGetGalleryName -TrustRepository -ErrorVariable err -ErrorAction SilentlyContinue + $pkg = Get-PSResource "NonExistantModule" + $pkg.Name | Should -BeNullOrEmpty + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "InstallPackageFailure,Microsoft.PowerShell.PowerShellGet.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 $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $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 $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $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 $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $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 $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $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 $NuGetGalleryName -TrustRepository -ErrorAction SilentlyContinue + } + catch + {} + $Error[0].FullyQualifiedErrorId | Should -be "IncorrectVersionFormat,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + + $res = Get-PSResource $testModuleName + $res | Should -BeNullOrEmpty + } + + It "Install resource when given Name, Version '*', should install the latest version" { + Install-PSResource -Name $testModuleName -Version "*" -Repository $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $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 $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $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 $NuGetGalleryName | Install-PSResource -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.0" + } + + It "Install resource under specified in PSModulePath" { + Install-PSResource -Name $testModuleName -Repository $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + ($env:PSModulePath).Contains($pkg.InstalledLocation) + } + + It "Install resource with companyname, copyright and repository source location and validate properties" { + Install-PSResource -Name $testModuleName -Version "5.2.5-alpha001" -Repository $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Version | Should -Be "5.2.5" + $pkg.Prerelease | Should -Be "alpha001" + + $pkg.CompanyName | Should -Be "Anam Navied" + $pkg.Copyright | Should -Be "(c) Anam Navied. All rights reserved." + $pkg.RepositorySourceLocation | Should -Be $NuGetGalleryUri + } + + # Windows only + It "Install resource under CurrentUser scope - Windows only" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name $testModuleName -Repository $NuGetGalleryName -TrustRepository -Scope CurrentUser + $pkg = Get-PSResource $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 "testmodule99" -Repository $NuGetGalleryName -TrustRepository -Scope AllUsers -Verbose + $pkg = Get-Module "testmodule99" -ListAvailable + $pkg.Name | Should -Be "testmodule99" + $pkg.Path.ToString().Contains("Program Files") + } + + # Windows only + It "Install resource under no specified scope - Windows only" -Skip:(!(Get-IsWindows)) { + Install-PSResource -Name $testModuleName -Repository $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $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 $NuGetGalleryName -TrustRepository -Scope CurrentUser + $pkg = Get-PSResource $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 $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $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 $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + Install-PSResource -Name $testModuleName -Repository $NuGetGalleryName -TrustRepository -WarningVariable WarningVar -warningaction SilentlyContinue + $WarningVar | Should -Not -BeNullOrEmpty + } + + It "Reinstall resource that is already installed with -Reinstall parameter" { + Install-PSResource -Name $testModuleName -Repository $NuGetGalleryName -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.0" + Install-PSResource -Name $testModuleName -Repository $NuGetGalleryName -Reinstall -TrustRepository + $pkg = Get-PSResource $testModuleName + $pkg.Name | Should -Be $testModuleName + $pkg.Version | Should -Be "5.0.0" + } + + # It "Restore resource after reinstall fails" { + # Install-PSResource -Name $testModuleName -Repository $NuGetGalleryName -TrustRepository + # $pkg = Get-PSResource $testModuleName + # $pkg.Name | Should -Contain $testModuleName + # $pkg.Version | Should -Contain "5.0.0" + + # $resourcePath = Split-Path -Path $pkg.InstalledLocation -Parent + # $resourceFiles = Get-ChildItem -Path $resourcePath -Recurse + + # # Lock resource file to prevent reinstall from succeeding. + # $fs = [System.IO.File]::Open($resourceFiles[0].FullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) + # try + # { + # # Reinstall of resource should fail with one of its files locked. + # Install-PSResource -Name $testModuleName -Repository $NuGetGalleryName -TrustRepository -Reinstall -ErrorVariable ev -ErrorAction Silent + # $ev.FullyQualifiedErrorId | Should -BeExactly 'InstallPackageFailed,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource' + # } + # finally + # { + # $fs.Close() + # } + + # # Verify that resource module has been restored. + # (Get-ChildItem -Path $resourcePath -Recurse).Count | Should -BeExactly $resourceFiles.Count + # } + + # It "Install resource that requires accept license with -AcceptLicense flag" { + # Install-PSResource -Name "testModuleWithlicense" -Repository $TestGalleryName -AcceptLicense + # $pkg = Get-PSResource "testModuleWithlicense" + # $pkg.Name | Should -Be "testModuleWithlicense" + # $pkg.Version | Should -Be "0.0.3.0" + # } + + It "Install PSResourceInfo object piped in" { + Find-PSResource -Name $testModuleName -Version "1.0.0.0" -Repository $NuGetGalleryName | Install-PSResource -TrustRepository + $res = Get-PSResource -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 $NuGetGalleryName -PassThru -TrustRepository + $res.Name | Should -Contain $testModuleName + } + + It "Install modules using -RequiredResource with hashtable" { + $rrHash = @{ + test_module = @{ + version = "[1.0.0,5.0.0)" + repository = $NuGetGalleryName + } + + test_module2 = @{ + version = "[1.0.0,5.0.0]" + repository = $NuGetGalleryName + prerelease = "true" + } + + TestModule99 = @{ + repository = $NuGetGalleryName + } + } + + Install-PSResource -RequiredResource $rrHash -TrustRepository + + $res1 = Get-PSResource $testModuleName + $res1.Name | Should -Be $testModuleName + $res1.Version | Should -Be "3.0.0" + + $res2 = Get-PSResource $testModuleName2 + $res2.Name | Should -Be $testModuleName2 + $res2.Version | Should -Be "5.0.0" + + $res3 = Get-PSResource "TestModule99" + $res3.Name | Should -Be "TestModule99" + $res3.Version | Should -Be "0.0.93" + } + + It "Install modules using -RequiredResource with JSON string" { + $rrJSON = "{ + 'test_module': { + 'version': '[1.0.0,5.0.0)', + 'repository': 'NuGetGallery' + }, + 'test_module2': { + 'version': '[1.0.0,5.0.0]', + 'repository': 'PSGallery', + 'prerelease': 'true' + }, + 'TestModule99': { + 'repository': 'NuGetGallery' + } + }" + + Install-PSResource -RequiredResource $rrJSON -TrustRepository + + $res1 = Get-PSResource $testModuleName + $res1.Name | Should -Be $testModuleName + $res1.Version | Should -Be "3.0.0" + + $res2 = Get-PSResource $testModuleName2 + $res2.Name | Should -Be $testModuleName2 + $res2.Version | Should -Be "5.0.0.0" + + $res3 = Get-PSResource "testModule99" + $res3.Name | Should -Be "testModule99" + $res3.Version | Should -Be "0.0.93" + } + + It "Install modules using -RequiredResourceFile with PSD1 file" { + $rrFilePSD1 = Join-Path -Path "$((Get-Item $psscriptroot).parent)" -ChildPath $RequiredResourcePSD1FileName + + Install-PSResource -RequiredResourceFile $rrFilePSD1 -TrustRepository + + $res1 = Get-PSResource $testModuleName + $res1.Name | Should -Be $testModuleName + $res1.Version | Should -Be "3.0.0.0" + + $res2 = Get-PSResource $testModuleName2 -Version "2.5.0-beta" + $res2.Name | Should -Be $testModuleName2 + $res2.Version | Should -Be "2.5.0" + $res2.Prerelease | Should -Be "beta" + + $res3 = Get-PSResource "testModule99" + $res3.Name | Should -Be "testModule99" + $res3.Version | Should -Be "0.0.93" + } + + It "Install modules using -RequiredResourceFile with JSON file" { + $rrFileJSON = Join-Path -Path "$((Get-Item $psscriptroot).parent)" -ChildPath $RequiredResourceJSONFileName + + Install-PSResource -RequiredResourceFile $rrFileJSON -TrustRepository + + $res1 = Get-PSResource $testModuleName + $res1.Name | Should -Be $testModuleName + $res1.Version | Should -Be "3.0.0.0" + + $res2 = Get-PSResource $testModuleName2 -Version "2.5.0-beta" + $res2.Name | Should -Be $testModuleName2 + $res2.Version | Should -Be "2.5.0" + $res2.Prerelease | Should -Be "beta" + + $res3 = Get-PSResource "testModule99" + $res3.Name | Should -Be "testModule99" + $res3.Version | Should -Be "0.0.93" + } +} +<# Temporarily commented until -Tag is implemented for this Describe block +Describe 'Test Install-PSResource for interactive and root user scenarios' { + + BeforeAll{ + $TestGalleryName = Get-PoshTestGalleryName + $NuGetGalleryName = Get-PSGalleryName + $NuGetGalleryName = Get-NuGetGalleryName + Get-NewPSResourceRepositoryFile + Register-LocalRepos + } + + AfterEach { + Uninstall-PSResource "TestModule", "testModuleWithlicense" -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 "TestModule" -Repository $TestGalleryName -Scope AllUsers + $pkg = Get-Module "TestModule" -ListAvailable + $pkg.Name | Should -Be "TestModule" + $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 "testModuleWithlicense" -Repository $TestGalleryName + $pkg = Get-PSResource "testModuleWithlicense" + $pkg.Name | Should -Be "testModuleWithlicense" + $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 "TestModule" -Repository $TestGalleryName -confirm:$false + + $pkg = Get-Module "TestModule" -ListAvailable + $pkg.Name | Should -Be "TestModule" + + Set-PSResourceRepository PoshTestGallery -Trusted + } +} +#> diff --git a/test/PSGetTestUtils.psm1 b/test/PSGetTestUtils.psm1 index 358b12ccc..759aa433a 100644 --- a/test/PSGetTestUtils.psm1 +++ b/test/PSGetTestUtils.psm1 @@ -19,10 +19,8 @@ $script:IsCoreCLR = $PSVersionTable.ContainsKey('PSEdition') -and $PSVersionTabl $script:PSGalleryName = 'PSGallery' $script:PSGalleryLocation = 'https://www.powershellgallery.com/api/v2' -$script:PoshTestGalleryName = 'PoshTestGallery' -$script:PostTestGalleryLocation = 'https://www.poshtestgallery.com/api/v2' - $script:NuGetGalleryName = 'NuGetGallery' +$script:NuGetGalleryLocation = 'https://api.nuget.org/v3/index.json' if($script:IsInbox) { @@ -141,6 +139,12 @@ function Get-NuGetGalleryName { return $script:NuGetGalleryName } + +function Get-NuGetGalleryLocation +{ + return $script:NuGetGalleryLocation +} + function Get-PSGalleryName { return $script:PSGalleryName @@ -149,15 +153,6 @@ function Get-PSGalleryName function Get-PSGalleryLocation { return $script:PSGalleryLocation } - -function Get-PoshTestGalleryName { - return $script:PoshTestGalleryName -} - -function Get-PoshTestGalleryLocation { - return $script:PostTestGalleryLocation -} - function Get-NewTestDirs { Param( [string[]] @@ -408,7 +403,13 @@ function Get-ModuleResourcePublishedToLocalRepoTestDrive $repoName, [string] - $packageVersion + $packageVersion, + + [string] + $prereleaseLabel, + + [string[]] + $tags ) Get-TestDriveSetUp @@ -417,7 +418,28 @@ function Get-ModuleResourcePublishedToLocalRepoTestDrive $null = New-Item -Path $publishModuleBase -ItemType Directory -Force $version = $packageVersion - New-ModuleManifest -Path (Join-Path -Path $publishModuleBase -ChildPath "$publishModuleName.psd1") -ModuleVersion $version -Description "$publishModuleName module" + if (!$tags -or ($tags.Count -eq 0)) + { + if (!$prereleaseLabel) + { + New-ModuleManifest -Path (Join-Path -Path $publishModuleBase -ChildPath "$publishModuleName.psd1") -ModuleVersion $version -Description "$publishModuleName module" + } + else + { + New-ModuleManifest -Path (Join-Path -Path $publishModuleBase -ChildPath "$publishModuleName.psd1") -ModuleVersion $version -Prerelease $prereleaseLabel -Description "$publishModuleName module" + } + } + else { + # tags is not null or is empty + if (!$prereleaseLabel) + { + New-ModuleManifest -Path (Join-Path -Path $publishModuleBase -ChildPath "$publishModuleName.psd1") -ModuleVersion $version -Description "$publishModuleName module" -Tags $tags + } + else + { + New-ModuleManifest -Path (Join-Path -Path $publishModuleBase -ChildPath "$publishModuleName.psd1") -ModuleVersion $version -Prerelease $prereleaseLabel -Description "$publishModuleName module" -Tags $tags + } + } Publish-PSResource -Path $publishModuleBase -Repository $repoName } diff --git a/test/SavePSResourceTests/SavePSResourceLocalTests.ps1 b/test/SavePSResourceTests/SavePSResourceLocalTests.ps1 index 29e7a2913..63071cf0d 100644 --- a/test/SavePSResourceTests/SavePSResourceLocalTests.ps1 +++ b/test/SavePSResourceTests/SavePSResourceLocalTests.ps1 @@ -108,9 +108,11 @@ Describe 'Test HTTP Save-PSResource for local repositories' { } It "Save module as a nupkg" { - Save-PSResource -Name $moduleName -Version "1.0.0" -Repository $localRepo -Path $SaveDir -AsNupkg -TrustRepository - $pkgDir = Get-ChildItem -Path $SaveDir | Where-Object Name -eq "test_module.1.0.0.nupkg" - $pkgDir | Should -Not -BeNullOrEmpty + Save-PSResource -Name $moduleName -Version "1.0.0" -Repository $localRepo -Path $SaveDir -AsNupkg -TrustRepository -WarningVariable WarningVar -warningaction SilentlyContinue + $WarningVar | Should -Not -BeNullOrEmpty + # not yet implemented + # $pkgDir = Get-ChildItem -Path $SaveDir | Where-Object Name -eq "$moduleName.1.0.0.nupkg" + # $pkgDir | Should -Not -BeNullOrEmpty } It "Save module and include XML metadata file" { diff --git a/test/SavePSResourceTests/SavePSResourceV2Tests.ps1 b/test/SavePSResourceTests/SavePSResourceV2Tests.ps1 index 887ad3c9d..daba6ce8c 100644 --- a/test/SavePSResourceTests/SavePSResourceV2Tests.ps1 +++ b/test/SavePSResourceTests/SavePSResourceV2Tests.ps1 @@ -165,6 +165,8 @@ Describe 'Test HTTP Save-PSResource for V2 Server Protocol' { # Save module that is not authenticode signed # Should FAIL to save the module It "Save module that is not authenticode signed" -Skip:(!(Get-IsWindows)) { - { Save-PSResource -Name $testModuleName -Version "5.0.0" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository -Path $SaveDir -ErrorAction SilentlyContinue } | Should -Throw -ErrorId "GetAuthenticodeSignatureError,Microsoft.PowerShell.PowerShellGet.Cmdlets.SavePSResource" + Save-PSResource -Name $testModuleName -Version "5.0.0" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository -Path $SaveDir -ErrorVariable err -ErrorAction SilentlyContinue + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "InstallPackageFailure,Microsoft.PowerShell.PowerShellGet.Cmdlets.SavePSResource" } } \ No newline at end of file diff --git a/test/SavePSResourceTests/SavePSResourceV3Tests.ps1 b/test/SavePSResourceTests/SavePSResourceV3Tests.ps1 index 1fa51b9a0..945685c3c 100644 --- a/test/SavePSResourceTests/SavePSResourceV3Tests.ps1 +++ b/test/SavePSResourceTests/SavePSResourceV3Tests.ps1 @@ -139,6 +139,8 @@ Describe 'Test HTTP Save-PSResource for V3 Server Protocol' { # Save module that is not authenticode signed # Should FAIL to save the module It "Save module that is not authenticode signed" -Skip:(!(Get-IsWindows)) { - { Save-PSResource -Name $testModuleName -Version "5.0.0" -AuthenticodeCheck -Repository $NuGetGalleryName -TrustRepository -Path $SaveDir -ErrorAction SilentlyContinue } | Should -Throw -ErrorId "GetAuthenticodeSignatureError,Microsoft.PowerShell.PowerShellGet.Cmdlets.SavePSResource" + Save-PSResource -Name $testModuleName -Version "5.0.0" -AuthenticodeCheck -Repository $NuGetGalleryName -TrustRepository -Path $SaveDir -ErrorVariable err -ErrorAction SilentlyContinue + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "InstallPackageFailure,Microsoft.PowerShell.PowerShellGet.Cmdlets.SavePSResource" } } \ No newline at end of file diff --git a/test/UpdatePSResourceTests/UpdatePSResourceV2Tests.ps1 b/test/UpdatePSResourceTests/UpdatePSResourceV2Tests.ps1 index 29b0bbaeb..5ddb55bb9 100644 --- a/test/UpdatePSResourceTests/UpdatePSResourceV2Tests.ps1 +++ b/test/UpdatePSResourceTests/UpdatePSResourceV2Tests.ps1 @@ -338,12 +338,14 @@ Describe 'Test HTTP Update-PSResource for V2 Server Protocol' { $res1.Version | Should -Be "1.4.3" } - # Update to module 1.4.4.1 (with incorrect catalog file) - # Should FAIL to update the module - It "Update module with incorrect catalog file" -Skip:(!(Get-IsWindows)) { - Install-PSResource -Name $PackageManagement -Version "1.4.2" -Repository $PSGalleryName -TrustRepository - { Update-PSResource -Name $PackageManagement -Version "1.4.4.1" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository -ErrorAction SilentlyContinue} | Should -Throw -ErrorId "GetAuthenticodeSignatureError,Microsoft.PowerShell.PowerShellGet.Cmdlets.UpdatePSResource" - } + # # Update to module 1.4.4.1 (with incorrect catalog file) + # # Should FAIL to update the module + # It "Update module with incorrect catalog file" -Skip:(!(Get-IsWindows)) { + # Install-PSResource -Name $PackageManagement -Version "1.4.2" -Reinstall -Repository $PSGalleryName -TrustRepository + # Update-PSResource -Name $PackageManagement -Version "1.4.4.1" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository -ErrorVariable err -ErrorAction SilentlyContinue + # $err.Count | Should -Not -Be 0 + # $err[0].FullyQualifiedErrorId | Should -BeExactly "InstallPackageFailure,Microsoft.PowerShell.PowerShellGet.Cmdlets.UpdatePSResource" + # } # Update to module 1.4.7 (is authenticode signed and has NO catalog file) # Should update successfully @@ -371,6 +373,8 @@ Describe 'Test HTTP Update-PSResource for V2 Server Protocol' { # Should throw It "Update script that is not signed" -Skip:(!(Get-IsWindows)) { Install-PSResource -Name "TestTestScript" -Version "1.0" -Repository $PSGalleryName -TrustRepository - { Update-PSResource -Name "TestTestScript" -Version "1.3.1.1" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository -ErrorAction SilentlyContinue } | Should -Throw -ErrorId "GetAuthenticodeSignatureError,Microsoft.PowerShell.PowerShellGet.Cmdlets.UpdatePSResource" + Update-PSResource -Name "TestTestScript" -Version "1.3.1.1" -AuthenticodeCheck -Repository $PSGalleryName -TrustRepository -ErrorVariable err -ErrorAction SilentlyContinue + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "InstallPackageFailure,Microsoft.PowerShell.PowerShellGet.Cmdlets.UpdatePSResource" } }