diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 13b30af22e8682..7b849e1bea38c5 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -75,14 +75,6 @@ jobs: # Limiting interp runs as we don't need as much coverage. - (Debian.12.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-12-helix-amd64 - # Linux s390x - - ${{ if eq(parameters.platform, 'linux_s390x') }}: - - Ubuntu.2004.S390X.Experimental.Open - - # Linux PPC64le - - ${{ if eq(parameters.platform, 'linux_ppc64le') }}: - - Ubuntu.2204.PPC64le.Experimental.Open - # OSX arm64 - ${{ if eq(parameters.platform, 'osx_arm64') }}: - OSX.1200.ARM64.Open diff --git a/eng/pipelines/runtime-community.yml b/eng/pipelines/runtime-community.yml index b7a21f588973c1..446996e505b72b 100644 --- a/eng/pipelines/runtime-community.yml +++ b/eng/pipelines/runtime-community.yml @@ -71,17 +71,6 @@ extends: eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_mono_excluding_wasm.containsChange'], true), eq(variables['isRollingBuild'], true)) - # extra steps, run tests - postBuildSteps: - - template: /eng/pipelines/libraries/helix.yml - parameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) - condition: >- - or( - eq(variables['librariesContainsChange'], true), - eq(variables['monoContainsChange'], true), - eq(variables['isRollingBuild'], true)) # # Build the whole product using Mono diff --git a/src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs b/src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs index 3d5b902ff1ad4f..f16e4e1d0e8e7a 100644 --- a/src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs +++ b/src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs @@ -111,6 +111,35 @@ public void ActivateClass_IgnoreAppLocalHostFxr() } } + [Fact] + public void ActivateClass_IgnoreWorkingDirectory() + { + using (TestArtifact cwd = TestArtifact.Create("cwd")) + { + // Validate that hosting components in the working directory will not be used + File.Copy(Binaries.CoreClr.MockPath, Path.Combine(cwd.Location, Binaries.CoreClr.FileName)); + File.Copy(Binaries.HostFxr.MockPath_5_0, Path.Combine(cwd.Location, Binaries.HostFxr.FileName)); + File.Copy(Binaries.HostPolicy.MockPath, Path.Combine(cwd.Location, Binaries.HostPolicy.FileName)); + + string[] args = { + "comhost", + "synchronous", + "1", + sharedState.ComHostPath, + sharedState.ClsidString + }; + sharedState.CreateNativeHostCommand(args, TestContext.BuiltDotNet.BinPath) + .WorkingDirectory(cwd.Location) + .Execute() + .Should().Pass() + .And.HaveStdOutContaining("New instance of Server created") + .And.HaveStdOutContaining($"Activation of {sharedState.ClsidString} succeeded.") + .And.ResolveHostFxr(TestContext.BuiltDotNet) + .And.ResolveHostPolicy(TestContext.BuiltDotNet) + .And.ResolveCoreClr(TestContext.BuiltDotNet); + } + } + [Fact] public void ActivateClass_ValidateIErrorInfoResult() { diff --git a/src/installer/tests/HostActivation.Tests/NativeHosting/Ijwhost.cs b/src/installer/tests/HostActivation.Tests/NativeHosting/Ijwhost.cs index fa00b0419a85ef..35d6e2af1298e4 100644 --- a/src/installer/tests/HostActivation.Tests/NativeHosting/Ijwhost.cs +++ b/src/installer/tests/HostActivation.Tests/NativeHosting/Ijwhost.cs @@ -89,6 +89,32 @@ public void LoadLibrary_ContextConfig(bool load_isolated) } } + [Fact] + public void LoadLibrary_IgnoreWorkingDirectory() + { + using (TestArtifact cwd = TestArtifact.Create("cwd")) + { + // Validate that hosting components in the working directory will not be used + File.Copy(Binaries.CoreClr.MockPath, Path.Combine(cwd.Location, Binaries.CoreClr.FileName)); + File.Copy(Binaries.HostFxr.MockPath_5_0, Path.Combine(cwd.Location, Binaries.HostFxr.FileName)); + File.Copy(Binaries.HostPolicy.MockPath, Path.Combine(cwd.Location, Binaries.HostPolicy.FileName)); + + string [] args = { + "ijwhost", + sharedState.IjwApp.AppDll, + "NativeEntryPoint" + }; + sharedState.CreateNativeHostCommand(args, TestContext.BuiltDotNet.BinPath) + .WorkingDirectory(cwd.Location) + .Execute() + .Should().Pass() + .And.HaveStdOutContaining("[C++/CLI] NativeEntryPoint: calling managed class") + .And.HaveStdOutContaining("[C++/CLI] ManagedClass: AssemblyLoadContext = \"Default\" System.Runtime.Loader.DefaultAssemblyLoadContext") + .And.ResolveHostFxr(TestContext.BuiltDotNet) + .And.ResolveHostPolicy(TestContext.BuiltDotNet) + .And.ResolveCoreClr(TestContext.BuiltDotNet); + } + } [Fact] public void LoadLibraryWithoutRuntimeConfigButActiveRuntime() diff --git a/src/installer/tests/HostActivation.Tests/NativeHosting/LoadAssemblyAndGetFunctionPointer.cs b/src/installer/tests/HostActivation.Tests/NativeHosting/LoadAssemblyAndGetFunctionPointer.cs index 39cdc5edb4ca35..6f7cae81047915 100644 --- a/src/installer/tests/HostActivation.Tests/NativeHosting/LoadAssemblyAndGetFunctionPointer.cs +++ b/src/installer/tests/HostActivation.Tests/NativeHosting/LoadAssemblyAndGetFunctionPointer.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.IO; using System.Linq; using Microsoft.DotNet.Cli.Build.Framework; @@ -231,6 +232,37 @@ public void CallDelegateOnComponentContext_UnhandledException() .And.ExecuteFunctionPointerWithException(entryPoint, 1); } + [Fact] + public void CallDelegateOnComponentContext_IgnoreWorkingDirectory() + { + using (TestArtifact cwd = TestArtifact.Create("cwd")) + { + // Validate that hosting components in the working directory will not be used + File.Copy(Binaries.CoreClr.MockPath, Path.Combine(cwd.Location, Binaries.CoreClr.FileName)); + File.Copy(Binaries.HostPolicy.MockPath, Path.Combine(cwd.Location, Binaries.HostPolicy.FileName)); + + var component = sharedState.Component; + string[] args = + { + ComponentLoadAssemblyAndGetFunctionPointerArg, + sharedState.HostFxrPath, + component.RuntimeConfigJson, + component.AppDll, + sharedState.ComponentTypeName, + sharedState.ComponentEntryPoint1, + }; + + sharedState.CreateNativeHostCommand(args, sharedState.DotNetRoot) + .WorkingDirectory(cwd.Location) + .Execute() + .Should().Pass() + .And.InitializeContextForConfig(component.RuntimeConfigJson) + .And.ExecuteFunctionPointer(sharedState.ComponentEntryPoint1, 1, 1) + .And.ResolveHostPolicy(TestContext.BuiltDotNet) + .And.ResolveCoreClr(TestContext.BuiltDotNet); + } + } + public class SharedTestState : SharedTestStateBase { public string HostFxrPath { get; } diff --git a/src/installer/tests/HostActivation.Tests/NativeHosting/FunctionPointerResultExtensions.cs b/src/installer/tests/HostActivation.Tests/NativeHosting/NativeHostingResultExtensions.cs similarity index 69% rename from src/installer/tests/HostActivation.Tests/NativeHosting/FunctionPointerResultExtensions.cs rename to src/installer/tests/HostActivation.Tests/NativeHosting/NativeHostingResultExtensions.cs index 09fdc52bc186bf..9a0447a219dcb9 100644 --- a/src/installer/tests/HostActivation.Tests/NativeHosting/FunctionPointerResultExtensions.cs +++ b/src/installer/tests/HostActivation.Tests/NativeHosting/NativeHostingResultExtensions.cs @@ -2,10 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.IO; namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting { - internal static class FunctionPointerResultExtensions + internal static class NativeHostingResultExtensions { public static FluentAssertions.AndConstraint ExecuteFunctionPointer(this CommandResultAssertions assertion, string methodName, int callCount, int returnValue) { @@ -47,5 +48,21 @@ public static FluentAssertions.AndConstraint ExecuteWit { return assertion.HaveStdOutContaining($"{assemblyName}: Location = '{location}'"); } + + public static FluentAssertions.AndConstraint ResolveHostFxr(this CommandResultAssertions assertion, Microsoft.DotNet.Cli.Build.DotNetCli dotnet) + { + return assertion.HaveStdErrContaining($"Resolved fxr [{dotnet.GreatestVersionHostFxrFilePath}]"); + } + + public static FluentAssertions.AndConstraint ResolveHostPolicy(this CommandResultAssertions assertion, Microsoft.DotNet.Cli.Build.DotNetCli dotnet) + { + return assertion.HaveStdErrContaining($"{Binaries.HostPolicy.FileName} directory is [{dotnet.GreatestVersionSharedFxPath}]"); + } + + public static FluentAssertions.AndConstraint ResolveCoreClr(this CommandResultAssertions assertion, Microsoft.DotNet.Cli.Build.DotNetCli dotnet) + { + return assertion.HaveStdErrContaining($"CoreCLR path = '{Path.Combine(dotnet.GreatestVersionSharedFxPath, Binaries.CoreClr.FileName)}'") + .And.HaveStdErrContaining($"CoreCLR dir = '{dotnet.GreatestVersionSharedFxPath}{Path.DirectorySeparatorChar}'"); + } } } diff --git a/src/native/corehost/apphost/standalone/hostfxr_resolver.cpp b/src/native/corehost/apphost/standalone/hostfxr_resolver.cpp index 073445177993cc..c8e5000805289a 100644 --- a/src/native/corehost/apphost/standalone/hostfxr_resolver.cpp +++ b/src/native/corehost/apphost/standalone/hostfxr_resolver.cpp @@ -118,6 +118,11 @@ hostfxr_resolver_t::hostfxr_resolver_t(const pal::string_t& app_root) { m_status_code = StatusCode::CoreHostLibMissingFailure; } + else if (!pal::is_path_rooted(m_fxr_path)) + { + // We should always be loading hostfxr from an absolute path + m_status_code = StatusCode::CoreHostLibMissingFailure; + } else if (pal::load_library(&m_fxr_path, &m_hostfxr_dll)) { m_status_code = StatusCode::Success; diff --git a/src/native/corehost/fxr/standalone/hostpolicy_resolver.cpp b/src/native/corehost/fxr/standalone/hostpolicy_resolver.cpp index 4e75400a04a81b..6092fea3cd8d9f 100644 --- a/src/native/corehost/fxr/standalone/hostpolicy_resolver.cpp +++ b/src/native/corehost/fxr/standalone/hostpolicy_resolver.cpp @@ -180,6 +180,10 @@ int hostpolicy_resolver::load( return StatusCode::CoreHostLibMissingFailure; } + // We should always be loading hostpolicy from an absolute path + if (!pal::is_path_rooted(host_path)) + return StatusCode::CoreHostLibMissingFailure; + // Load library // We expect to leak hostpolicy - just as we do not unload coreclr, we do not unload hostpolicy if (!pal::load_library(&host_path, &g_hostpolicy)) diff --git a/src/native/corehost/fxr_resolver.h b/src/native/corehost/fxr_resolver.h index b61f3b8fb4e6dc..88fc9f8781efdd 100644 --- a/src/native/corehost/fxr_resolver.h +++ b/src/native/corehost/fxr_resolver.h @@ -55,6 +55,10 @@ int load_fxr_and_get_delegate(hostfxr_delegate_type type, THostPathToConfigCallb return StatusCode::CoreHostLibMissingFailure; } + // We should always be loading hostfxr from an absolute path + if (!pal::is_path_rooted(fxr_path)) + return StatusCode::CoreHostLibMissingFailure; + // Load library if (!pal::load_library(&fxr_path, &fxr)) { diff --git a/src/native/corehost/hostpolicy/deps_resolver.cpp b/src/native/corehost/hostpolicy/deps_resolver.cpp index 55d9bd8f948868..0e87b791cfbfc4 100644 --- a/src/native/corehost/hostpolicy/deps_resolver.cpp +++ b/src/native/corehost/hostpolicy/deps_resolver.cpp @@ -830,15 +830,21 @@ bool deps_resolver_t::resolve_probe_dirs( } } - // If the deps file is missing add known locations. - if (!get_app_deps().exists()) + // If the deps file is missing for the app, add known locations. + // For libhost scenarios, there is no app or app path + if (m_host_mode != host_mode_t::libhost && !get_app_deps().exists()) { + assert(!m_app_dir.empty()); + // App local path add_unique_path(asset_type, m_app_dir, &items, output, &non_serviced, core_servicing); - // deps_resolver treats being able to get the coreclr path as optional, so we ignore the return value here. - // The caller is responsible for checking whether coreclr path is set and handling as appropriate. - (void) file_exists_in_dir(m_app_dir, LIBCORECLR_NAME, &m_coreclr_path); + if (m_coreclr_path.empty()) + { + // deps_resolver treats being able to get the coreclr path as optional, so we ignore the return value here. + // The caller is responsible for checking whether coreclr path is set and handling as appropriate. + (void) file_exists_in_dir(m_app_dir, LIBCORECLR_NAME, &m_coreclr_path); + } } // Handle any additional deps.json that were specified. diff --git a/src/native/corehost/hostpolicy/standalone/coreclr_resolver.cpp b/src/native/corehost/hostpolicy/standalone/coreclr_resolver.cpp index b040c3e8546278..8df8e395e3f259 100644 --- a/src/native/corehost/hostpolicy/standalone/coreclr_resolver.cpp +++ b/src/native/corehost/hostpolicy/standalone/coreclr_resolver.cpp @@ -13,6 +13,10 @@ bool coreclr_resolver_t::resolve_coreclr(const pal::string_t& libcoreclr_path, c pal::string_t coreclr_dll_path(libcoreclr_path); append_path(&coreclr_dll_path, LIBCORECLR_NAME); + // We should always be loading coreclr from an absolute path + if (!pal::is_path_rooted(coreclr_dll_path)) + return false; + if (!pal::load_library(&coreclr_dll_path, &coreclr_resolver_contract.coreclr)) { return false;