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);
        }
Ejemplo n.º 3
0
        //  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);
        }