Skip to content

Commit

Permalink
Ensure the namespaces filtering is respected in packages.config packa…
Browse files Browse the repository at this point in the history
…ge installation/updates in PMC (#4150)

* Add PMC Apex, End2End install/update tests.
  • Loading branch information
erdembayar authored Jul 17, 2021
1 parent 63b8dba commit cc3d62f
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ internal class ApexTestContext : IDisposable

public NuGetApexTestService NuGetApexTestService { get; }

public ApexTestContext(VisualStudioHost visualStudio, ProjectTemplate projectTemplate, ILogger logger, bool noAutoRestore = false, bool addNetStandardFeeds = false)
public ApexTestContext(VisualStudioHost visualStudio, ProjectTemplate projectTemplate, ILogger logger, bool noAutoRestore = false, bool addNetStandardFeeds = false, SimpleTestPathContext simpleTestPathContext = null)
{
logger.LogInformation("Creating test context");
_pathContext = new SimpleTestPathContext();
_pathContext = simpleTestPathContext ?? new SimpleTestPathContext();

if (noAutoRestore)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Threading.Tasks;
using Microsoft.Test.Apex.VisualStudio.Solution;
using NuGet.StaFact;
using NuGet.Test.Utility;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -291,6 +292,226 @@ public async Task InstallAndUpdatePackageWithSourceParameterWarnsAsync(ProjectTe
}
}

[NuGetWpfTheory]
[MemberData(nameof(GetPackagesConfigTemplates))]
public async Task InstallPackageForPC_PackageNamespace_WithSingleFeed(ProjectTemplate projectTemplate)
{
// Arrange
EnsureVisualStudioHost();

using var simpleTestPathContext = new SimpleTestPathContext();
string solutionDirectory = simpleTestPathContext.SolutionRoot;
var privateRepositoryPath = Path.Combine(solutionDirectory, "PrivateRepository");
Directory.CreateDirectory(privateRepositoryPath);

var packageName = "Contoso.A";
var packageVersion = "1.0.0";

await CommonUtility.CreatePackageInSourceAsync(privateRepositoryPath, packageName, packageVersion);

//Create nuget.config with Package namespace filtering rules.
CommonUtility.CreateConfigurationFile(Path.Combine(solutionDirectory, "NuGet.config"), $@"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key=""PrivateRepository"" value=""{privateRepositoryPath}"" />
</packageSources>
<packageNamespaces>
<packageSource key=""PrivateRepository"">
<namespace id=""Contoso.*"" />
<namespace id=""Test.*"" />
</packageSource>
</packageNamespaces>
//</configuration>");

using (var testContext = new ApexTestContext(VisualStudio, projectTemplate, XunitLogger, noAutoRestore: false, addNetStandardFeeds: false, simpleTestPathContext: simpleTestPathContext))
{
var nugetConsole = GetConsole(testContext.Project);

// Act
nugetConsole.InstallPackageFromPMC(packageName, packageVersion);

// Assert
CommonUtility.AssertPackageInPackagesConfig(VisualStudio, testContext.Project, packageName, packageVersion, XunitLogger);
}
}

[NuGetWpfTheory]
[MemberData(nameof(GetPackagesConfigTemplates))]
public async Task UpdatePackageForPC_PackageNamespace_WithSingleFeed(ProjectTemplate projectTemplate)
{
// Arrange
EnsureVisualStudioHost();

using var simpleTestPathContext = new SimpleTestPathContext();
string solutionDirectory = simpleTestPathContext.SolutionRoot;
var privateRepositoryPath = Path.Combine(solutionDirectory, "PrivateRepository");
Directory.CreateDirectory(privateRepositoryPath);

var packageName = "Contoso.A";
var packageVersion1 = "1.0.0";
var packageVersion2 = "2.0.0";

await CommonUtility.CreatePackageInSourceAsync(privateRepositoryPath, packageName, packageVersion1);
await CommonUtility.CreatePackageInSourceAsync(privateRepositoryPath, packageName, packageVersion2);

//Create nuget.config with Package namespace filtering rules.
CommonUtility.CreateConfigurationFile(Path.Combine(solutionDirectory, "NuGet.config"), $@"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key=""PrivateRepository"" value=""{privateRepositoryPath}"" />
</packageSources>
<packageNamespaces>
<packageSource key=""PrivateRepository"">
<namespace id=""Contoso.*"" />
<namespace id=""Test.*"" />
</packageSource>
</packageNamespaces>
//</configuration>");

using (var testContext = new ApexTestContext(VisualStudio, projectTemplate, XunitLogger, noAutoRestore: false, addNetStandardFeeds: false, simpleTestPathContext: simpleTestPathContext))
{
var nugetConsole = GetConsole(testContext.Project);

// Act
nugetConsole.InstallPackageFromPMC(packageName, packageVersion1);
nugetConsole.UpdatePackageFromPMC(packageName, packageVersion2);

// Assert
CommonUtility.AssertPackageInPackagesConfig(VisualStudio, testContext.Project, packageName, packageVersion2, XunitLogger);
}
}

[NuGetWpfTheory]
[MemberData(nameof(GetPackagesConfigTemplates))]
public async Task InstallPackageForPC_PackageNamespace_WithMultipleFeedsWithIdenticalPackages_InstallsCorrectPackage(ProjectTemplate projectTemplate)
{
// Arrange
EnsureVisualStudioHost();

using var simpleTestPathContext = new SimpleTestPathContext();
string solutionDirectory = simpleTestPathContext.SolutionRoot;
var packageName = "Contoso.A";
var packageVersion1 = "1.0.0";
var packageVersion2 = "2.0.0";

var opensourceRepositoryPath = Path.Combine(solutionDirectory, "OpensourceRepository");
Directory.CreateDirectory(opensourceRepositoryPath);

await CommonUtility.CreateNetCorePackageInSourceAsync(opensourceRepositoryPath, packageName, packageVersion1, "Thisisfromopensourcerepo1.txt");
await CommonUtility.CreateNetCorePackageInSourceAsync(opensourceRepositoryPath, packageName, packageVersion2, "Thisisfromopensourcerepo2.txt");

var privateRepositoryPath = Path.Combine(solutionDirectory, "PrivateRepository");
Directory.CreateDirectory(privateRepositoryPath);

await CommonUtility.CreateNetCorePackageInSourceAsync(privateRepositoryPath, packageName, packageVersion1, "Thisisfromprivaterepo1.txt");
await CommonUtility.CreateNetCorePackageInSourceAsync(privateRepositoryPath, packageName, packageVersion2, "Thisisfromprivaterepo2.txt");

//Create nuget.config with Package namespace filtering rules.
CommonUtility.CreateConfigurationFile(Path.Combine(solutionDirectory, "NuGet.config"), $@"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key=""ExternalRepository"" value=""{opensourceRepositoryPath}"" />
<add key=""PrivateRepository"" value=""{privateRepositoryPath}"" />
</packageSources>
<packageNamespaces>
<packageSource key=""externalRepository"">
<namespace id=""External.*"" />
<namespace id=""Others.*"" />
</packageSource>
<packageSource key=""PrivateRepository"">
<namespace id=""Contoso.*"" />
<namespace id=""Test.*"" />
</packageSource>
</packageNamespaces>
//</configuration>");

using (var testContext = new ApexTestContext(VisualStudio, projectTemplate, XunitLogger, noAutoRestore: false, addNetStandardFeeds: false, simpleTestPathContext: simpleTestPathContext))
{
var nugetConsole = GetConsole(testContext.Project);

// Act
nugetConsole.InstallPackageFromPMC(packageName, packageVersion1);

// Assert
CommonUtility.AssertPackageInPackagesConfig(VisualStudio, testContext.Project, packageName, packageVersion1, XunitLogger);

var packagesDirectory = Path.Combine(solutionDirectory, "packages");
var uniqueContentFile = Path.Combine(packagesDirectory, packageName + '.' + packageVersion1, "lib", "net5.0", "Thisisfromprivaterepo1.txt");
// Make sure name squatting package not restored from opensource repository.
Assert.True(File.Exists(uniqueContentFile));
}
}

[NuGetWpfTheory]
[MemberData(nameof(GetPackagesConfigTemplates))]
public async Task UpdatePackageForPC_PackageNamespace_WithMultipleFeedsWithIdenticalPackages_UpdatesCorrectPackage(ProjectTemplate projectTemplate)
{
// Arrange
EnsureVisualStudioHost();

using var simpleTestPathContext = new SimpleTestPathContext();
string solutionDirectory = simpleTestPathContext.SolutionRoot;
var packageName = "Contoso.A";
var packageVersion1 = "1.0.0";
var packageVersion2 = "2.0.0";

var opensourceRepositoryPath = Path.Combine(solutionDirectory, "OpensourceRepository");
Directory.CreateDirectory(opensourceRepositoryPath);

await CommonUtility.CreateNetCorePackageInSourceAsync(opensourceRepositoryPath, packageName, packageVersion1, "Thisisfromopensourcerepo1.txt");
await CommonUtility.CreateNetCorePackageInSourceAsync(opensourceRepositoryPath, packageName, packageVersion2, "Thisisfromopensourcerepo2.txt");

var privateRepositoryPath = Path.Combine(solutionDirectory, "PrivateRepository");
Directory.CreateDirectory(privateRepositoryPath);

await CommonUtility.CreateNetCorePackageInSourceAsync(privateRepositoryPath, packageName, packageVersion1, "Thisisfromprivaterepo1.txt");
await CommonUtility.CreateNetCorePackageInSourceAsync(privateRepositoryPath, packageName, packageVersion2, "Thisisfromprivaterepo2.txt");

//Create nuget.config with Package namespace filtering rules.
CommonUtility.CreateConfigurationFile(Path.Combine(solutionDirectory, "NuGet.config"), $@"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key=""ExternalRepository"" value=""{opensourceRepositoryPath}"" />
<add key=""PrivateRepository"" value=""{privateRepositoryPath}"" />
</packageSources>
<packageNamespaces>
<packageSource key=""externalRepository"">
<namespace id=""External.*"" />
<namespace id=""Others.*"" />
</packageSource>
<packageSource key=""PrivateRepository"">
<namespace id=""Contoso.*"" />
<namespace id=""Test.*"" />
</packageSource>
</packageNamespaces>
//</configuration>");

using (var testContext = new ApexTestContext(VisualStudio, projectTemplate, XunitLogger, noAutoRestore: false, addNetStandardFeeds: false, simpleTestPathContext: simpleTestPathContext))
{
var nugetConsole = GetConsole(testContext.Project);

// Act
nugetConsole.InstallPackageFromPMC(packageName, packageVersion1);
nugetConsole.UpdatePackageFromPMC(packageName, packageVersion2);

// Assert
CommonUtility.AssertPackageInPackagesConfig(VisualStudio, testContext.Project, packageName, packageVersion2, XunitLogger);

var packagesDirectory = Path.Combine(solutionDirectory, "packages");
var uniqueContentFile = Path.Combine(packagesDirectory, packageName + '.' + packageVersion2, "lib", "net5.0", "Thisisfromprivaterepo2.txt");
// Make sure name squatting package not restored from opensource repository.
Assert.True(File.Exists(uniqueContentFile));
}
}

// There is a bug with VS or Apex where NetCoreConsoleApp creates a netcore 2.1 project that is not supported by the sdk
// Commenting out any NetCoreConsoleApp template and swapping it for NetStandardClassLib as both are package ref.
public static IEnumerable<object[]> GetNetCoreTemplates()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,6 @@ public async Task InstallPackageFromUI_PackageNamespace_WithMultiFeed_Fails()
[StaFact]
public async Task UpdatePackageFromUI_PackageNamespace_WithSingleFeed_Succeeds()
{
// Arrange
// Arrange
EnsureVisualStudioHost();
var solutionService = VisualStudio.Get<SolutionService>();
Expand Down
20 changes: 20 additions & 0 deletions test/NuGet.Tests.Apex/NuGet.Tests.Apex/Utility/CommonUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ public static SimpleTestPackageContext CreateRepositoryCountersignedPackage(
return RepositoryCountersignPackage(authorSignedPackage, repoCertificate, v3ServiceIndexUrl, packageOwners, timestampProviderUrl);
}

public static async Task CreateNetCorePackageInSourceAsync(string packageSource, string packageName, string packageVersion, string requestAdditionalContent = null)
{
var package = CreateNetCorePackage(packageName, packageVersion, requestAdditionalContent);
await SimpleTestPackageUtility.CreatePackagesAsync(packageSource, package);
}

public static SimpleTestPackageContext AuthorSignPackage(
SimpleTestPackageContext package,
X509Certificate2 authorCertificate,
Expand Down Expand Up @@ -149,6 +155,20 @@ public static SimpleTestPackageContext CreatePackage(string packageName, string
return package;
}

public static SimpleTestPackageContext CreateNetCorePackage(string packageName, string packageVersion, string requestAdditionalContent)
{
var package = new SimpleTestPackageContext(packageName, packageVersion);
package.Files.Clear();
package.AddFile("lib/net5.0/_._");

if(!string.IsNullOrWhiteSpace(requestAdditionalContent))
{
package.AddFile("lib/net5.0/" + requestAdditionalContent);
}

return package;
}

public static void AssertPackageReferenceExists(VisualStudioHost visualStudio, ProjectTestExtension project, string packageName, string packageVersion, ILogger logger)
{
logger.LogInformation($"Checking for PackageReference {packageName} {packageVersion}");
Expand Down

0 comments on commit cc3d62f

Please sign in to comment.