File: GivenThatWeWantRuntimeConfigInBuiltProjectOutputGroup.cs
Web Access
Project: ..\..\..\test\Microsoft.NET.Build.Tests\Microsoft.NET.Build.Tests.csproj (Microsoft.NET.Build.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
#nullable disable
 
namespace Microsoft.NET.Build.Tests
{
    public class GivenThatWeWantRuntimeConfigInBuiltProjectOutputGroup : SdkTest
    {
        public GivenThatWeWantRuntimeConfigInBuiltProjectOutputGroup(ITestOutputHelper log) : base(log)
        {
        }
 
        [Theory]
        [InlineData("netcoreapp1.1")]
        [InlineData(ToolsetInfo.CurrentTargetFramework)]
        public void It_has_target_path_and_final_outputput_path_metadata(string targetFramework)
        {
            var testAsset = _testAssetsManager
                .CopyTestAsset("HelloWorld", identifier: targetFramework)
                .WithSource()
                .WithTargetFramework(targetFramework);
 
            var command = new GetValuesCommand(
                testAsset,
                "BuiltProjectOutputGroupOutput",
                GetValuesCommand.ValueType.Item)
            {
                MetadataNames = { "FinalOutputPath", "TargetPath" },
                DependsOnTargets = "BuiltProjectOutputGroup",
            };
 
            command.Execute().Should().Pass();
 
            var outputDirectory = command.GetOutputDirectory(targetFramework);
            var runtimeConfigFile = outputDirectory.File("HelloWorld.runtimeconfig.json");
            var (_, metadata) = command.GetValuesWithMetadata().Single(i => i.value == runtimeConfigFile.FullName);
 
            metadata.Count.Should().Be(2);
            metadata.Should().Contain(KeyValuePair.Create("FinalOutputPath", runtimeConfigFile.FullName));
            metadata.Should().Contain(KeyValuePair.Create("TargetPath", runtimeConfigFile.Name));
        }
 
        [Fact]
        public void It_has_runtime_config_properties_after_partial_build()
        {
            var testProject = new TestProject()
            {
                Name = "RuntimeConfigPartialBuild",
                TargetFrameworks = ToolsetInfo.CurrentTargetFramework,
                IsExe = true,
                RuntimeIdentifier = $"{ToolsetInfo.LatestWinRuntimeIdentifier}-x86"
            };
            var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name);
 
            var buildCommand = new BuildCommand(testAsset);
 
            buildCommand
                .Execute("/property:Configuration=Release")
                .Should()
                .Pass();
 
            var configFile = Path.Combine(buildCommand.GetOutputDirectory(configuration: "Release", runtimeIdentifier: testProject.RuntimeIdentifier).FullName, testProject.Name + ".runtimeconfig.json");
 
            File.Exists(configFile).Should().BeTrue();
            File.ReadAllText(configFile).Should().NotContain("\"System.Runtime.TieredCompilation\"");
            File.ReadAllText(configFile).Should().NotContain("\"System.GC.Concurrent\"");
            File.ReadAllText(configFile).Should().NotContain("\"System.Threading.ThreadPool.MinThreads\"");
            File.ReadAllText(configFile).Should().NotContain("\"System.Runtime.Loader.UseRidGraph\"");
 
            testAsset = testAsset.WithProjectChanges(project =>
            {
                var ns = project.Root.Name.Namespace;
                var propertyGroup = new XElement(ns + "PropertyGroup");
                project.Root.Add(propertyGroup);
                propertyGroup.Add(new XElement(ns + "TieredCompilation", "false"));
                propertyGroup.Add(new XElement(ns + "ConcurrentGarbageCollection", "false"));
                propertyGroup.Add(new XElement(ns + "ThreadPoolMinThreads", "2"));
                propertyGroup.Add(new XElement(ns + "UseRidGraph", "true"));
            });
 
            new BuildCommand(testAsset)
                .Execute("/property:Configuration=Release")
                .Should()
                .Pass();
 
            File.Exists(configFile).Should().BeTrue();
            File.ReadAllText(configFile).Should().Contain("\"System.Runtime.TieredCompilation\": false");
            File.ReadAllText(configFile).Should().Contain("\"System.GC.Concurrent\": false");
            File.ReadAllText(configFile).Should().Contain("\"System.Threading.ThreadPool.MinThreads\": 2");
            File.ReadAllText(configFile).Should().Contain("\"System.Runtime.Loader.UseRidGraph\": true");
        }
 
        [Fact]
        public void It_updates_runtime_config_properties_after_partial_build()
        {
            var testProject = new TestProject()
            {
                Name = "UpdateRuntimeConfigPartialBuild",
                TargetFrameworks = ToolsetInfo.CurrentTargetFramework,
                IsExe = true,
                RuntimeIdentifier = $"{ToolsetInfo.LatestWinRuntimeIdentifier}-x86"
            };
            var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name);
 
            testAsset = testAsset.WithProjectChanges(project =>
            {
                var ns = project.Root.Name.Namespace;
                var propertyGroup = new XElement(ns + "PropertyGroup");
                project.Root.Add(propertyGroup);
                propertyGroup.Add(new XElement(ns + "TieredCompilation", "true"));
                propertyGroup.Add(new XElement(ns + "ConcurrentGarbageCollection", "true"));
                propertyGroup.Add(new XElement(ns + "ThreadPoolMinThreads", "3"));
                propertyGroup.Add(new XElement(ns + "UseRidGraph", "false"));
            });
 
            var buildCommand = new BuildCommand(testAsset);
 
            buildCommand
                .Execute("/property:Configuration=Release")
                .Should()
                .Pass();
 
            var configFile = Path.Combine(buildCommand.GetOutputDirectory(configuration: "Release", runtimeIdentifier: testProject.RuntimeIdentifier).FullName, testProject.Name + ".runtimeconfig.json");
 
            File.Exists(configFile).Should().BeTrue();
            File.ReadAllText(configFile).Should().Contain("\"System.Runtime.TieredCompilation\": true");
            File.ReadAllText(configFile).Should().Contain("\"System.GC.Concurrent\": true");
            File.ReadAllText(configFile).Should().Contain("\"System.Threading.ThreadPool.MinThreads\": 3");
            File.ReadAllText(configFile).Should().Contain("\"System.Runtime.Loader.UseRidGraph\": false");
 
            testAsset = testAsset.WithProjectChanges(project =>
            {
                var ns = project.Root.Name.Namespace;
                var propertyGroup = new XElement(ns + "PropertyGroup");
                project.Root.Add(propertyGroup);
                propertyGroup.Add(new XElement(ns + "TieredCompilation", "false"));
                propertyGroup.Add(new XElement(ns + "ConcurrentGarbageCollection", "false"));
                propertyGroup.Add(new XElement(ns + "ThreadPoolMinThreads", "2"));
                propertyGroup.Add(new XElement(ns + "UseRidGraph", "true"));
            });
 
            new BuildCommand(testAsset)
                .Execute("/property:Configuration=Release")
                .Should()
                .Pass();
 
            File.Exists(configFile).Should().BeTrue();
            File.ReadAllText(configFile).Should().Contain("\"System.Runtime.TieredCompilation\": false");
            File.ReadAllText(configFile).Should().Contain("\"System.GC.Concurrent\": false");
            File.ReadAllText(configFile).Should().Contain("\"System.Threading.ThreadPool.MinThreads\": 2");
            File.ReadAllText(configFile).Should().Contain("\"System.Runtime.Loader.UseRidGraph\": true");
        }
    }
}