From 78083e7dd0d688c47c6bfbf2538e8032c0c023ae Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Wed, 9 Mar 2022 20:52:18 -0800 Subject: [PATCH] Add test for comhost with managed host (#66360) --- docs/workflow/testing/host/testing.md | 2 +- .../Assets/TestProjects/ManagedHost/App.manifest | 18 ++++++ .../Assets/TestProjects/ManagedHost/ManagedHost.cs | 22 +++++++ .../TestProjects/ManagedHost/ManagedHost.csproj | 1 + .../HostActivation.Tests/NativeHosting/Comhost.cs | 6 +- .../NativeHosting/ComhostSideBySide.cs | 74 +++++++++++++++++----- 6 files changed, 102 insertions(+), 21 deletions(-) create mode 100644 src/installer/tests/Assets/TestProjects/ManagedHost/App.manifest diff --git a/docs/workflow/testing/host/testing.md b/docs/workflow/testing/host/testing.md index 6a912e3..5139589 100644 --- a/docs/workflow/testing/host/testing.md +++ b/docs/workflow/testing/host/testing.md @@ -69,7 +69,7 @@ dotnet test artifacts/bin/HostActivation.Tests/Debug/net5.0/HostActivation.Tests To filter to specific tests within the test library, use the [filter options](https://docs.microsoft.com/dotnet/core/tools/dotnet-test#filter-option-details) available for `dotnet test`. For example: ``` -dotnet test artifacts/bin/HostActivation.Tests/Debug/net5.0/HostActivation.Tests.dll --filter DependencyResolution&category!=failing +dotnet test artifacts/bin/HostActivation.Tests/Debug/net5.0/HostActivation.Tests.dll --filter "DependencyResolution&category!=failing" ``` The `category!=failing` is to respect the [filtering traits](../libraries/filtering-tests.md) used by the runtime repo. diff --git a/src/installer/tests/Assets/TestProjects/ManagedHost/App.manifest b/src/installer/tests/Assets/TestProjects/ManagedHost/App.manifest new file mode 100644 index 0000000..dbc7d82 --- /dev/null +++ b/src/installer/tests/Assets/TestProjects/ManagedHost/App.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/src/installer/tests/Assets/TestProjects/ManagedHost/ManagedHost.cs b/src/installer/tests/Assets/TestProjects/ManagedHost/ManagedHost.cs index 8275112..6161d05 100644 --- a/src/installer/tests/Assets/TestProjects/ManagedHost/ManagedHost.cs +++ b/src/installer/tests/Assets/TestProjects/ManagedHost/ManagedHost.cs @@ -17,6 +17,17 @@ namespace ComClient switch (args[0]) { + case "comhost": + { + // args: ... + if (args.Length != 2) + { + throw new Exception("Invalid number of arguments passed"); + } + + ComTest(args[1]); + break; + } case "ijwhost": { // args: ... @@ -33,6 +44,17 @@ namespace ComClient } } + private static unsafe void ComTest(string clsidString) + { + Console.WriteLine($"Activating class ID {clsidString}"); + + Guid clsid = Guid.Parse(clsidString); + Type t = Type.GetTypeFromCLSID(clsid); + var server = Activator.CreateInstance(t); + + Console.WriteLine($"Activation of {clsidString} succeeded."); + } + private static unsafe void IjwTest(string libraryPath, string entryPointName) { Console.WriteLine($"Invoking {entryPointName} in '{libraryPath}'"); diff --git a/src/installer/tests/Assets/TestProjects/ManagedHost/ManagedHost.csproj b/src/installer/tests/Assets/TestProjects/ManagedHost/ManagedHost.csproj index 770abee..a2ce79e 100644 --- a/src/installer/tests/Assets/TestProjects/ManagedHost/ManagedHost.csproj +++ b/src/installer/tests/Assets/TestProjects/ManagedHost/ManagedHost.csproj @@ -7,6 +7,7 @@ $(TestTargetRid) true + App.manifest diff --git a/src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs b/src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs index d48d843..373dea3 100644 --- a/src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs +++ b/src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs @@ -13,6 +13,7 @@ using Xunit; namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting { + [PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows public class Comhost : IClassFixture { private readonly SharedTestState sharedState; @@ -23,7 +24,6 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting } [Theory] - [PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows [InlineData(1, true)] [InlineData(10, true)] [InlineData(10, false)] @@ -49,7 +49,6 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting } [Fact] - [PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows public void ActivateClass_IgnoreAppLocalHostFxr() { using (var fixture = sharedState.ComLibraryFixture.Copy()) @@ -77,7 +76,6 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting } [Fact] - [PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows public void ActivateClass_ValidateIErrorInfoResult() { using (var fixture = sharedState.ComLibraryFixture.Copy()) @@ -107,7 +105,6 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting } [Fact] - [PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows public void LoadTypeLibraries() { using (var fixture = sharedState.ComLibraryFixture.Copy()) @@ -185,7 +182,6 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting ComHostPath, ClsidMapPath, TypeLibraries); - } protected override void Dispose(bool disposing) diff --git a/src/installer/tests/HostActivation.Tests/NativeHosting/ComhostSideBySide.cs b/src/installer/tests/HostActivation.Tests/NativeHosting/ComhostSideBySide.cs index 623f93a..3837efc 100644 --- a/src/installer/tests/HostActivation.Tests/NativeHosting/ComhostSideBySide.cs +++ b/src/installer/tests/HostActivation.Tests/NativeHosting/ComhostSideBySide.cs @@ -13,6 +13,7 @@ using Xunit; namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting { + [PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows public class ComhostSideBySide : IClassFixture { private readonly SharedTestState sharedState; @@ -23,7 +24,6 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting } [Fact] - [PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows public void ActivateClass() { string [] args = { @@ -42,7 +42,6 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting } [Fact] - [PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows public void LocateEmbeddedTlb() { string [] args = { @@ -60,12 +59,37 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting .And.HaveStdOutContaining("Located type library by typeid."); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ManagedHost(bool selfContained) + { + string [] args = { + "comhost", + sharedState.ClsidString + }; + TestProjectFixture fixture = selfContained ? sharedState.ManagedHostFixture_SelfContained : sharedState.ManagedHostFixture_FrameworkDependent; + CommandResult result = Command.Create(fixture.TestProject.AppExe, args) + .EnableTracingAndCaptureOutputs() + .DotNetRoot(fixture.BuiltDotnet.BinPath) + .MultilevelLookup(false) + .Execute(); + + result.Should().Pass() + .And.HaveStdOutContaining("New instance of Server created") + .And.HaveStdOutContaining($"Activation of {sharedState.ClsidString} succeeded.") + .And.HaveStdErrContaining($"Executing as a {(selfContained ? "self-contained" : "framework-dependent")} app"); + } + public class SharedTestState : Comhost.SharedTestState { public string TypeLibId { get; } = "{20151109-a0e8-46ae-b28e-8ff2c0e72166}"; public string ComSxsPath { get; } + public TestProjectFixture ManagedHostFixture_FrameworkDependent { get; } + public TestProjectFixture ManagedHostFixture_SelfContained { get; } + public SharedTestState() { if (!OperatingSystem.IsWindows()) @@ -74,13 +98,14 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting return; } + string comsxsDirectory = BaseDirectory; + string regFreeManifestName = $"{ ComLibraryFixture.TestProject.AssemblyName }.X.manifest"; + string regFreeManifestPath = Path.Combine(comsxsDirectory, regFreeManifestName); using (var assemblyStream = new FileStream(ComLibraryFixture.TestProject.AppDll, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read)) using (var peReader = new System.Reflection.PortableExecutable.PEReader(assemblyStream)) { if (peReader.HasMetadata) { - string regFreeManifestPath = Path.Combine(BaseDirectory, $"{ ComLibraryFixture.TestProject.AssemblyName }.X.manifest"); - MetadataReader reader = peReader.GetMetadataReader(); RegFreeComManifest.CreateManifestFromClsidmap( ComLibraryFixture.TestProject.AssemblyName, @@ -93,24 +118,43 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting } } - string testDirectoryPath = Path.GetDirectoryName(NativeHostPath); string comsxsName = RuntimeInformationExtensions.GetExeFileNameForCurrentPlatform("comsxs"); - ComSxsPath = Path.Combine(testDirectoryPath, comsxsName); + ComSxsPath = Path.Combine(comsxsDirectory, comsxsName); File.Copy( Path.Combine(RepoDirectories.Artifacts, "corehost_test", comsxsName), ComSxsPath); - File.Copy( - ComHostPath, - Path.Combine(testDirectoryPath, Path.GetFileName(ComHostPath))); - File.Copy( + + ManagedHostFixture_FrameworkDependent = new TestProjectFixture("ManagedHost", RepoDirectories) + .EnsureRestored() + .PublishProject(selfContained: false, extraArgs: "/p:RegFreeCom=true"); + File.Copy(regFreeManifestPath, Path.Combine(ManagedHostFixture_FrameworkDependent.TestProject.BuiltApp.Location, regFreeManifestName)); + + ManagedHostFixture_SelfContained = new TestProjectFixture("ManagedHost", RepoDirectories) + .EnsureRestored() + .PublishProject(selfContained: true, extraArgs: "/p:RegFreeCom=true"); + File.Copy(regFreeManifestPath, Path.Combine(ManagedHostFixture_SelfContained.TestProject.BuiltApp.Location, regFreeManifestName)); + + // Copy the ComLibrary output and comhost to the ComSxS and ManagedHost directories + string[] toCopy = { ComLibraryFixture.TestProject.AppDll, - Path.Combine(testDirectoryPath, Path.GetFileName(ComLibraryFixture.TestProject.AppDll))); - File.Copy( ComLibraryFixture.TestProject.DepsJson, - Path.Combine(testDirectoryPath, Path.GetFileName(ComLibraryFixture.TestProject.DepsJson))); - File.Copy( ComLibraryFixture.TestProject.RuntimeConfigJson, - Path.Combine(testDirectoryPath, Path.GetFileName(ComLibraryFixture.TestProject.RuntimeConfigJson))); + ComHostPath, + }; + foreach (string filePath in toCopy) + { + File.Copy(filePath, Path.Combine(comsxsDirectory, Path.GetFileName(filePath))); + File.Copy(filePath, Path.Combine(ManagedHostFixture_FrameworkDependent.TestProject.BuiltApp.Location, Path.GetFileName(filePath))); + File.Copy(filePath, Path.Combine(ManagedHostFixture_SelfContained.TestProject.BuiltApp.Location, Path.GetFileName(filePath))); + } + } + + protected override void Dispose(bool disposing) + { + ManagedHostFixture_FrameworkDependent.Dispose(); + ManagedHostFixture_SelfContained.Dispose(); + + base.Dispose(disposing); } } } -- 2.7.4