Add test for comhost with managed host (#66360)
authorElinor Fung <elfung@microsoft.com>
Thu, 10 Mar 2022 04:52:18 +0000 (20:52 -0800)
committerGitHub <noreply@github.com>
Thu, 10 Mar 2022 04:52:18 +0000 (20:52 -0800)
docs/workflow/testing/host/testing.md
src/installer/tests/Assets/TestProjects/ManagedHost/App.manifest [new file with mode: 0644]
src/installer/tests/Assets/TestProjects/ManagedHost/ManagedHost.cs
src/installer/tests/Assets/TestProjects/ManagedHost/ManagedHost.csproj
src/installer/tests/HostActivation.Tests/NativeHosting/Comhost.cs
src/installer/tests/HostActivation.Tests/NativeHosting/ComhostSideBySide.cs

index 6a912e3..5139589 100644 (file)
@@ -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 (file)
index 0000000..dbc7d82
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
+  <assemblyIdentity
+    type="win32"
+    name="ManagedHost"
+    version="1.0.0.0" />
+
+  <dependency>
+    <dependentAssembly>
+      <!-- RegFree COM -->
+      <assemblyIdentity
+          type="win32"
+          name="ComLibrary.X"
+          version="1.0.0.0"/>
+    </dependentAssembly>
+  </dependency>
+
+</assembly>
index 8275112..6161d05 100644 (file)
@@ -17,6 +17,17 @@ namespace ComClient
 
             switch (args[0])
             {
+                case "comhost":
+                {
+                    // args: ... <clsid>
+                    if (args.Length != 2)
+                    {
+                        throw new Exception("Invalid number of arguments passed");
+                    }
+
+                    ComTest(args[1]);
+                    break;
+                }
                 case "ijwhost":
                 {
                     // args: ... <ijw_library_path> <entry_point>
@@ -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}'");
index 770abee..a2ce79e 100644 (file)
@@ -7,6 +7,7 @@
     <RuntimeIdentifier>$(TestTargetRid)</RuntimeIdentifier>
 
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <ApplicationManifest Condition="'$(RegFreeCom)' == 'true'">App.manifest</ApplicationManifest>
   </PropertyGroup>
 
 </Project>
index d48d843..373dea3 100644 (file)
@@ -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<Comhost.SharedTestState>
     {
         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)
index 623f93a..3837efc 100644 (file)
@@ -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<ComhostSideBySide.SharedTestState>
     {
         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);
             }
         }
     }