From: Elinor Fung Date: Fri, 24 Feb 2023 18:14:43 +0000 (-0800) Subject: Add tests that use the host's computed RID (#82574) X-Git-Tag: accepted/tizen/unified/riscv/20231226.055536~3825 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=570ff7cc05cfad4fa2a44dca6ee97e0ea3e13695;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Add tests that use the host's computed RID (#82574) Add tests that rely on the host's computed RID (sets `DOTNET_RUNTIME_ID` to empty, which we treat as the same as not set) and use the fallback graph from the built `Microsoft.NETCore.App.deps.json`. --- diff --git a/src/installer/tests/HostActivation.Tests/DependencyResolution/DependencyResolutionCommandResultExtensions.cs b/src/installer/tests/HostActivation.Tests/DependencyResolution/DependencyResolutionCommandResultExtensions.cs index 14b44a1..0f66913 100644 --- a/src/installer/tests/HostActivation.Tests/DependencyResolution/DependencyResolutionCommandResultExtensions.cs +++ b/src/installer/tests/HostActivation.Tests/DependencyResolution/DependencyResolutionCommandResultExtensions.cs @@ -147,6 +147,12 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution return assertion.HaveStdErrContaining($"Using specified additional deps.json: '{depsFilePath}'"); } + public static AndConstraint HaveUsedFallbackRid(this CommandResultAssertions assertion, bool usedFallbackRid) + { + string msg = "Falling back to base HostRID"; + return usedFallbackRid ? assertion.HaveStdErrContaining(msg) : assertion.NotHaveStdErrContaining(msg); + } + private static string GetAppMockPropertyValue(CommandResultAssertions assertion, string propertyName) => GetMockPropertyValue(assertion, $"mock property[{propertyName}] = "); diff --git a/src/installer/tests/HostActivation.Tests/DependencyResolution/RidAssetResolution.cs b/src/installer/tests/HostActivation.Tests/DependencyResolution/RidAssetResolution.cs index 9c6cb58..b90d252 100644 --- a/src/installer/tests/HostActivation.Tests/DependencyResolution/RidAssetResolution.cs +++ b/src/installer/tests/HostActivation.Tests/DependencyResolution/RidAssetResolution.cs @@ -2,6 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.DotNet.Cli.Build; +using Microsoft.Extensions.DependencyModel; using Xunit; namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution @@ -24,6 +29,8 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution string excludedNativeLibraryPaths, Action appCustomizer = null); + protected const string UnknownRid = "unknown-rid"; + private const string LinuxAssembly = "linux/LinuxAssembly.dll"; private const string MacOSAssembly = "osx/MacOSAssembly.dll"; private const string WindowsAssembly = "win/WindowsAssembly.dll"; @@ -43,13 +50,15 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution rid, includedPath, excludedPath, null, null); } - [Fact] - public void RidSpecificAssembly_UnknownRid() + [Theory] + [InlineData(null)] // RID is computed at run-time + [InlineData(UnknownRid)] // RID is from a compile-time fallback + public void RidSpecificAssembly_CurrentRid(string rid) { string includedPath = null; string excludedPath = null; - // When the RID is unknown, the host uses a compile-time fallback based on the target OS + // Host should resolve to the RID corresponding to the platform on which it is running if (OperatingSystem.IsLinux()) { includedPath = LinuxAssembly; @@ -71,7 +80,7 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution excludedPath = $"{LinuxAssembly};{MacOSAssembly};{WindowsAssembly}"; } - RidSpecificAssembly("unknown-rid", includedPath, excludedPath); + RidSpecificAssembly(rid, includedPath, excludedPath); } [Theory] @@ -89,12 +98,15 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution rid, null, null, includedPath, excludedPath); } - [Fact] - public void RidSpecificNativeLibrary_UnknownRid() + [Theory] + [InlineData(null)] // RID is computed at run-time + [InlineData(UnknownRid)] // RID is from a compile-time fallback + public void RidSpecificNativeLibrary_CurrentRid(string rid) { - // When the RID is unknown, the host uses a compile-time fallback based on the target OS string includedPath; string excludedPath; + + // Host should resolve to the RID corresponding to the platform on which it is running if (OperatingSystem.IsLinux()) { includedPath = "linux"; @@ -164,7 +176,7 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution } [Theory] - // For "win" RIDs the DependencyLib which is RID-agnostic will not be included, + // For "win" RIDs the DependencyLib which is RID-agnostic will not be included, // since there are other assembly (runtime) assets with more specific RID match. [InlineData("win10-x64", "win/ManagedWin.dll;win/AnotherWin.dll", "native/win10-x64;native/win10-x64-2")] [InlineData("win10-x86", "win/ManagedWin.dll;win/AnotherWin.dll", "native/win-x86")] @@ -196,7 +208,7 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution .WithPackage("ridAgnosticLib", "2.0.0", p => p .WithAssemblyGroup(null, g => g.WithAsset("PortableLib.dll").WithAsset("PortableLib2.dll"))), rid: rid, - // The PortableLib an PortableLib2 are from a separate package which has no RID specific assets, + // The PortableLib an PortableLib2 are from a separate package which has no RID specific assets, // so the RID-agnostic assets are always included includedAssemblyPaths: expectedAssemblyPath + ";PortableLib.dll;PortableLib2.dll", excludedAssemblyPaths: null, includedNativeLibraryPaths: expectedNativePath, excludedNativeLibraryPaths: null); @@ -204,8 +216,30 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution public class SharedTestState : ComponentSharedTestStateBase { + public DotNetCli DotNetWithNetCoreApp_RuntimeFallbacks { get; } + public SharedTestState() : base() { + DotNetWithNetCoreApp_RuntimeFallbacks = DotNet("WithNetCoreApp_RuntimeFallbacks") + .AddMicrosoftNETCoreAppFrameworkMockCoreClr("4.0.0", UseFallbacksFromBuiltDotNet) + .Build(); + } + + protected void UseFallbacksFromBuiltDotNet(NetCoreAppBuilder builder) + { + IReadOnlyList fallbacks; + string depsJson = Path.Combine(new DotNetCli(BuiltDotnetPath).GreatestVersionSharedFxPath, $"{Constants.MicrosoftNETCoreApp}.deps.json"); + using (FileStream fileStream = File.Open(depsJson, FileMode.Open)) + using (DependencyContextJsonReader reader = new DependencyContextJsonReader()) + { + fallbacks = reader.Read(fileStream).RuntimeGraph; + } + + builder.RuntimeFallbacks.Clear(); + foreach (RuntimeFallbacks fallback in fallbacks) + { + builder.WithRuntimeFallbacks(fallback.Runtime, fallback.Fallbacks.ToArray()); + } } } } @@ -234,7 +268,9 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution .WithCustomizer(appCustomizer) .Build()) { - SharedState.DotNetWithNetCoreApp.Exec(app.AppDll) + // Use the fallbacks from the product when testing the computed RID + DotNetCli dotnet = rid == null ? SharedState.DotNetWithNetCoreApp_RuntimeFallbacks : SharedState.DotNetWithNetCoreApp; + dotnet.Exec(app.AppDll) .EnableTracingAndCaptureOutputs() .RuntimeId(rid) .Execute() @@ -242,7 +278,8 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution .And.HaveResolvedAssembly(includedAssemblyPaths, app) .And.NotHaveResolvedAssembly(excludedAssemblyPaths, app) .And.HaveResolvedNativeLibraryPath(includedNativeLibraryPaths, app) - .And.NotHaveResolvedNativeLibraryPath(excludedNativeLibraryPaths, app); + .And.NotHaveResolvedNativeLibraryPath(excludedNativeLibraryPaths, app) + .And.HaveUsedFallbackRid(rid == UnknownRid); } } } @@ -270,14 +307,17 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution .WithPackage("NativeDependency", "1.0.0", p => assetsCustomizer?.Invoke(p)) .WithCustomizer(appCustomizer)); - SharedState.RunComponentResolutionTest(component, command => command + // Use the fallbacks from the product when testing the computed RID + DotNetCli dotnet = rid == null ? SharedState.DotNetWithNetCoreApp_RuntimeFallbacks : SharedState.DotNetWithNetCoreApp; + SharedState.RunComponentResolutionTest(component.AppDll, SharedState.FrameworkReferenceApp, dotnet.GreatestVersionHostFxrPath, command => command .RuntimeId(rid)) .Should().Pass() .And.HaveSuccessfullyResolvedComponentDependencies() .And.HaveResolvedComponentDependencyAssembly(includedAssemblyPaths, component) .And.NotHaveResolvedComponentDependencyAssembly(excludedAssemblyPaths, component) .And.HaveResolvedComponentDependencyNativeLibraryPath(includedNativeLibraryPaths, component) - .And.NotHaveResolvedComponentDependencyNativeLibraryPath(excludedNativeLibraryPaths, component); + .And.NotHaveResolvedComponentDependencyNativeLibraryPath(excludedNativeLibraryPaths, component) + .And.HaveUsedFallbackRid(rid == UnknownRid); } } @@ -327,7 +367,8 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution .Should().Pass() .And.HaveSuccessfullyResolvedComponentDependencies() .And.NotHaveResolvedComponentDependencyAssembly(assemblyPaths, component) - .And.NotHaveResolvedComponentDependencyNativeLibraryPath(nativeLibrarypaths, component); + .And.NotHaveResolvedComponentDependencyNativeLibraryPath(nativeLibrarypaths, component) + .And.HaveUsedFallbackRid(true); } public class ComponentSharedTestState : SharedTestState @@ -342,7 +383,7 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution } // Run the tests on a portable component hosted by a self-contained app which does have a RID fallback graph - // This is testing the scenario after SDK starts generating RID fallback graph even for self-contained apps + // This is testing the scenario after SDK starts generating RID fallback graph even for self-contained apps // - https://github.com/dotnet/sdk/issues/3361 public class PortableComponentOnSelfContainedAppRidAssetResolutionWithRidFallbackGraph : RidAssetResolutionBase, @@ -369,26 +410,35 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution .WithPackage("NativeDependency", "1.0.0", p => assetsCustomizer?.Invoke(p)) .WithCustomizer(appCustomizer)); - SharedState.RunComponentResolutionTest(component.AppDll, ComponentSharedState.HostApp, ComponentSharedState.HostApp.Location, command => command + // Use the fallbacks from the product when testing the computed RID + TestApp app = rid == null ? ComponentSharedState.HostApp_RuntimeFallbacks : ComponentSharedState.HostApp; + SharedState.RunComponentResolutionTest(component.AppDll, app, app.Location, command => command .RuntimeId(rid)) .Should().Pass() .And.HaveSuccessfullyResolvedComponentDependencies() .And.HaveResolvedComponentDependencyAssembly(includedAssemblyPaths, component) .And.NotHaveResolvedComponentDependencyAssembly(excludedAssemblyPaths, component) .And.HaveResolvedComponentDependencyNativeLibraryPath(includedNativeLibraryPaths, component) - .And.NotHaveResolvedComponentDependencyNativeLibraryPath(excludedNativeLibraryPaths, component); + .And.NotHaveResolvedComponentDependencyNativeLibraryPath(excludedNativeLibraryPaths, component) + .And.HaveUsedFallbackRid(rid == UnknownRid); } public class ComponentSharedTestState : SharedTestState { public TestApp HostApp { get; } + public TestApp HostApp_RuntimeFallbacks { get; } public ComponentSharedTestState() { HostApp = CreateSelfContainedAppWithMockCoreClr( - "ComponentHostSelfContainedApp", + "ComponentHostSelfContainedApp", "1.0.0", b => b.WithStandardRuntimeFallbacks()); + + HostApp_RuntimeFallbacks = CreateSelfContainedAppWithMockCoreClr( + "ComponentHostSelfContainedApp_RuntimeFallbacks", + "1.0.0", + UseFallbacksFromBuiltDotNet); } } }