public void Nuget_reference_compat(string referencerTarget, string testDescription, string rawDependencyTargets, bool restoreSucceeds, bool buildSucceeds) { string referencerDirectoryNamePostfix = "_" + referencerTarget + "_" + testDescription; TestProject referencerProject = GetTestProject(ConstantStringValues.ReferencerDirectoryName, referencerTarget, true); // Skip running test if not running on Windows // https://github.com/dotnet/sdk/issues/335 if (!(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || referencerProject.BuildsOnNonWindows)) { return; } foreach (string dependencyTarget in rawDependencyTargets.Split(',', ';', ' ').ToList()) { TestProject dependencyProject = GetTestProject(ConstantStringValues.DependencyDirectoryNamePrefix + dependencyTarget.Replace('.', '_'), dependencyTarget, true); TestPackageReference dependencyPackageReference = new TestPackageReference( dependencyProject.Name, "1.0.0", ConstantStringValues.ConstructNuGetPackageReferencePath(dependencyProject)); // Skip creating the NuGet package if not running on Windows; or if the NuGet package already exists // https://github.com/dotnet/sdk/issues/335 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || dependencyProject.BuildsOnNonWindows) { if (!dependencyPackageReference.NuGetPackageExists()) { // Create the NuGet packages var dependencyTestAsset = _testAssetsManager.CreateTestProject(dependencyProject, ConstantStringValues.TestDirectoriesNamePrefix, ConstantStringValues.NuGetSharedDirectoryNamePostfix); var dependencyRestoreCommand = dependencyTestAsset.GetRestoreCommand(Log, relativePath: dependencyProject.Name).Execute().Should().Pass(); var dependencyProjectDirectory = Path.Combine(dependencyTestAsset.TestRoot, dependencyProject.Name); var dependencyPackCommand = new PackCommand(Log, dependencyProjectDirectory); var dependencyPackResult = dependencyPackCommand.Execute().Should().Pass(); } referencerProject.PackageReferences.Add(dependencyPackageReference); } } // Skip running tests if no NuGet packages are referenced // https://github.com/dotnet/sdk/issues/335 if (referencerProject.PackageReferences == null) { return; } // Set the referencer project as an Exe unless it targets .NET Standard if (!referencerProject.ShortTargetFrameworkIdentifiers.Contains(ConstantStringValues.NetstandardToken)) { referencerProject.IsExe = true; } // Create the referencing app and run the compat test var referencerTestAsset = _testAssetsManager.CreateTestProject(referencerProject, ConstantStringValues.TestDirectoriesNamePrefix, referencerDirectoryNamePostfix); var referencerRestoreCommand = referencerTestAsset.GetRestoreCommand(Log, relativePath: referencerProject.Name); List <string> referencerRestoreSources = new List <string>(); // Modify the restore command to refer to the created NuGet packages foreach (TestPackageReference packageReference in referencerProject.PackageReferences) { var source = Path.Combine(packageReference.NupkgPath, packageReference.ID, "bin", "Debug"); referencerRestoreSources.Add(source); } NuGetConfigWriter.Write(referencerTestAsset.TestRoot, referencerRestoreSources); if (restoreSucceeds) { referencerRestoreCommand.Execute().Should().Pass(); } else { referencerRestoreCommand.Execute().Should().Fail(); } var referencerBuildCommand = new BuildCommand(Log, Path.Combine(referencerTestAsset.TestRoot, referencerProject.Name)); var referencerBuildResult = referencerBuildCommand.Execute(); if (buildSucceeds) { referencerBuildResult.Should().Pass(); } else { referencerBuildResult.Should().Fail().And.HaveStdOutContaining("It cannot be referenced by a project that targets"); } }
private void It_targets_the_right_framework( string testIdentifier, string targetFramework, string runtimeFrameworkVersion, bool selfContained, bool isExe, string expectedPackageVersion, string expectedRuntimeVersion, string extraMSBuildArguments = null) { string runtimeIdentifier = null; if (selfContained) { runtimeIdentifier = EnvironmentInfo.GetCompatibleRid(targetFramework); } var testProject = new TestProject() { Name = "FrameworkTargetTest", TargetFrameworks = targetFramework, RuntimeFrameworkVersion = runtimeFrameworkVersion, IsSdkProject = true, IsExe = isExe, RuntimeIdentifier = runtimeIdentifier }; var extraArgs = extraMSBuildArguments?.Split(' ') ?? Array.Empty <string>(); var testAsset = _testAssetsManager.CreateTestProject(testProject, testIdentifier) .Restore(Log, testProject.Name, extraArgs); NuGetConfigWriter.Write(testAsset.TestRoot, NuGetConfigWriter.DotnetCoreBlobFeed); var buildCommand = new BuildCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); buildCommand .Execute(extraArgs) .Should() .Pass(); var outputDirectory = buildCommand.GetOutputDirectory(targetFramework, runtimeIdentifier: runtimeIdentifier); if (isExe) { // Self-contained apps don't write a framework version to the runtimeconfig, so only check this for framework-dependent apps if (!selfContained) { string runtimeConfigFile = Path.Combine(outputDirectory.FullName, testProject.Name + ".runtimeconfig.json"); string runtimeConfigContents = File.ReadAllText(runtimeConfigFile); JObject runtimeConfig = JObject.Parse(runtimeConfigContents); string actualRuntimeFrameworkVersion = ((JValue)runtimeConfig["runtimeOptions"]["framework"]["version"]).Value <string>(); actualRuntimeFrameworkVersion.Should().Be(expectedRuntimeVersion); } var runtimeconfigDevFileName = testProject.Name + ".runtimeconfig.dev.json"; outputDirectory.Should() .HaveFile(runtimeconfigDevFileName); string devruntimeConfigContents = File.ReadAllText(Path.Combine(outputDirectory.FullName, runtimeconfigDevFileName)); JObject devruntimeConfig = JObject.Parse(devruntimeConfigContents); var additionalProbingPaths = ((JArray)devruntimeConfig["runtimeOptions"]["additionalProbingPaths"]).Values <string>(); // can't use Path.Combine on segments with an illegal `|` character var expectedPath = $"{Path.Combine(FileConstants.UserProfileFolder, ".dotnet", "store")}{Path.DirectorySeparatorChar}|arch|{Path.DirectorySeparatorChar}|tfm|"; additionalProbingPaths.Should().Contain(expectedPath); } LockFile lockFile = LockFileUtilities.GetLockFile(Path.Combine(buildCommand.ProjectRootPath, "obj", "project.assets.json"), NullLogger.Instance); var target = lockFile.GetTarget(NuGetFramework.Parse(targetFramework), null); var netCoreAppLibrary = target.Libraries.Single(l => l.Name == "Microsoft.NETCore.App"); netCoreAppLibrary.Version.ToString().Should().Be(expectedPackageVersion); }
// This method duplicates a lot of logic from the CLI in order to test generating deps files for tools in the SDK repo private CommandResult GenerateDepsAndRunTool(TestProject toolProject, [CallerMemberName] string callingMethod = "") { DeleteFolder(Path.Combine(TestContext.Current.NuGetCachePath, toolProject.Name.ToLowerInvariant())); DeleteFolder(Path.Combine(TestContext.Current.NuGetCachePath, ".tools", toolProject.Name.ToLowerInvariant())); var toolProjectInstance = _testAssetsManager.CreateTestProject(toolProject, callingMethod, identifier: toolProject.Name); NuGetConfigWriter.Write(toolProjectInstance.TestRoot, NuGetConfigWriter.DotnetCoreMyGetFeed); toolProjectInstance.Restore(Log, toolProject.Name, "/v:n"); var packCommand = new PackCommand(Log, Path.Combine(toolProjectInstance.TestRoot, toolProject.Name)); packCommand.Execute() .Should() .Pass(); string nupkgPath = Path.Combine(packCommand.ProjectRootPath, "bin", "Debug"); TestProject toolReferencer = new TestProject() { Name = "ToolReferencer", IsSdkProject = true, TargetFrameworks = "netcoreapp2.0" }; var toolReferencerInstance = _testAssetsManager.CreateTestProject(toolReferencer, callingMethod, identifier: toolReferencer.Name) .WithProjectChanges(project => { var ns = project.Root.Name.Namespace; var itemGroup = new XElement(ns + "ItemGroup"); project.Root.Add(itemGroup); itemGroup.Add(new XElement(ns + "DotNetCliToolReference", new XAttribute("Include", toolProject.Name), new XAttribute("Version", "1.0.0"))); }); List <string> sources = new List <string>() { NuGetConfigWriter.DotnetCoreMyGetFeed }; sources.Add(nupkgPath); NuGetConfigWriter.Write(toolReferencerInstance.TestRoot, sources); var restoreCommand = toolReferencerInstance.GetRestoreCommand(Log, toolReferencer.Name); restoreCommand.Execute("/v:n").Should().Pass(); string toolAssetsFilePath = Path.Combine(TestContext.Current.NuGetCachePath, ".tools", toolProject.Name.ToLowerInvariant(), "1.0.0", toolProject.TargetFrameworks, "project.assets.json"); var toolAssetsFile = new LockFileFormat().Read(toolAssetsFilePath); var args = new List <string>(); string currentToolsetSdksPath; if (TestContext.Current.ToolsetUnderTest.SdksPath == null) { // We don't have an overridden path to the SDKs, so figure out which version of the SDK we're using and // calculate the path based on that var command = new DotnetCommand(Log, "--version"); var testDirectory = TestDirectory.Create(Path.Combine(TestContext.Current.TestExecutionDirectory, "sdkversion")); command.WorkingDirectory = testDirectory.Path; var result = command.Execute(); result.Should().Pass(); var sdkVersion = result.StdOut.Trim(); string dotnetDir = Path.GetDirectoryName(TestContext.Current.ToolsetUnderTest.DotNetHostPath); currentToolsetSdksPath = Path.Combine(dotnetDir, "sdk", sdkVersion, "Sdks"); } else { currentToolsetSdksPath = TestContext.Current.ToolsetUnderTest.SdksPath; } string generateDepsProjectDirectoryPath = Path.Combine(currentToolsetSdksPath, "Microsoft.NET.Sdk", "targets", "GenerateDeps"); string generateDepsProjectFileName = "GenerateDeps.proj"; args.Add($"/p:ProjectAssetsFile=\"{toolAssetsFilePath}\""); args.Add($"/p:ToolName={toolProject.Name}"); string depsFilePath = Path.Combine(Path.GetDirectoryName(toolAssetsFilePath), toolProject.Name + ".deps.json"); args.Add($"/p:ProjectDepsFilePath={depsFilePath}"); var toolTargetFramework = toolAssetsFile.Targets.First().TargetFramework.GetShortFolderName(); args.Add($"/p:TargetFramework={toolProject.TargetFrameworks}"); // Look for the .props file in the Microsoft.NETCore.App package, until NuGet // generates .props and .targets files for tool restores (https://github.com/NuGet/Home/issues/5037) var platformLibrary = toolAssetsFile.Targets .Single() .Libraries .FirstOrDefault(e => e.Name.Equals("Microsoft.NETCore.App", StringComparison.OrdinalIgnoreCase)); if (platformLibrary != null) { string buildRelativePath = platformLibrary.Build.FirstOrDefault()?.Path; var platformLibraryPath = GetPackageDirectory(toolAssetsFile, platformLibrary); if (platformLibraryPath != null && buildRelativePath != null) { // Get rid of "_._" filename buildRelativePath = Path.GetDirectoryName(buildRelativePath); string platformLibraryBuildFolderPath = Path.Combine(platformLibraryPath, buildRelativePath); var platformLibraryPropsFile = Directory.GetFiles(platformLibraryBuildFolderPath, "*.props").FirstOrDefault(); if (platformLibraryPropsFile != null) { args.Add($"/p:AdditionalImport={platformLibraryPropsFile}"); } } } args.Add("/v:n"); var generateDepsCommand = new MSBuildCommand(Log, "BuildDepsJson", generateDepsProjectDirectoryPath, generateDepsProjectFileName); generateDepsCommand.Execute(args.ToArray()) .Should() .Pass(); new DirectoryInfo(generateDepsProjectDirectoryPath) .Should() .OnlyHaveFiles(new[] { generateDepsProjectFileName }); var toolLibrary = toolAssetsFile.Targets .Single() .Libraries.FirstOrDefault( l => StringComparer.OrdinalIgnoreCase.Equals(l.Name, toolProject.Name)); var toolAssembly = toolLibrary?.RuntimeAssemblies .FirstOrDefault(r => Path.GetFileNameWithoutExtension(r.Path) == toolProject.Name); var toolPackageDirectory = GetPackageDirectory(toolAssetsFile, toolLibrary); var toolAssemblyPath = Path.Combine( toolPackageDirectory, toolAssembly.Path); var dotnetArgs = new List <string>(); dotnetArgs.Add("exec"); dotnetArgs.Add("--depsfile"); dotnetArgs.Add(depsFilePath); foreach (var packageFolder in GetNormalizedPackageFolders(toolAssetsFile)) { dotnetArgs.Add("--additionalprobingpath"); dotnetArgs.Add(packageFolder); } dotnetArgs.Add(Path.GetFullPath(toolAssemblyPath)); var toolCommandSpec = new SdkCommandSpec() { FileName = TestContext.Current.ToolsetUnderTest.DotNetHostPath, Arguments = dotnetArgs }; TestContext.Current.AddTestEnvironmentVariables(toolCommandSpec); ICommand toolCommand = toolCommandSpec.ToCommand().CaptureStdOut(); var toolResult = toolCommand.Execute(); return(toolResult); }