Skip to content

Commit

Permalink
Add test for comhost with managed host (dotnet#66360)
Browse files Browse the repository at this point in the history
  • Loading branch information
elinor-fung authored Mar 10, 2022
1 parent f091e55 commit 78083e7
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 21 deletions.
2 changes: 1 addition & 1 deletion docs/workflow/testing/host/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
18 changes: 18 additions & 0 deletions src/installer/tests/Assets/TestProjects/ManagedHost/App.manifest
Original file line number Diff line number Diff line change
@@ -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>
22 changes: 22 additions & 0 deletions src/installer/tests/Assets/TestProjects/ManagedHost/ManagedHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ static void Main(string[] args)

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>
Expand All @@ -33,6 +44,17 @@ static void Main(string[] args)
}
}

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}'");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<RuntimeIdentifier>$(TestTargetRid)</RuntimeIdentifier>

<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ApplicationManifest Condition="'$(RegFreeCom)' == 'true'">App.manifest</ApplicationManifest>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

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;
Expand All @@ -23,7 +24,6 @@ public Comhost(SharedTestState sharedTestState)
}

[Theory]
[PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows
[InlineData(1, true)]
[InlineData(10, true)]
[InlineData(10, false)]
Expand All @@ -49,7 +49,6 @@ public void ActivateClass(int count, bool synchronous)
}

[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows
public void ActivateClass_IgnoreAppLocalHostFxr()
{
using (var fixture = sharedState.ComLibraryFixture.Copy())
Expand Down Expand Up @@ -77,7 +76,6 @@ public void ActivateClass_IgnoreAppLocalHostFxr()
}

[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows
public void ActivateClass_ValidateIErrorInfoResult()
{
using (var fixture = sharedState.ComLibraryFixture.Copy())
Expand Down Expand Up @@ -107,7 +105,6 @@ public void ActivateClass_ValidateIErrorInfoResult()
}

[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows
public void LoadTypeLibraries()
{
using (var fixture = sharedState.ComLibraryFixture.Copy())
Expand Down Expand Up @@ -185,7 +182,6 @@ public SharedTestState()
ComHostPath,
ClsidMapPath,
TypeLibraries);

}

protected override void Dispose(bool disposing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

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;
Expand All @@ -23,7 +24,6 @@ public ComhostSideBySide(SharedTestState sharedTestState)
}

[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows
public void ActivateClass()
{
string [] args = {
Expand All @@ -42,7 +42,6 @@ public void ActivateClass()
}

[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // COM activation is only supported on Windows
public void LocateEmbeddedTlb()
{
string [] args = {
Expand All @@ -60,12 +59,37 @@ public void LocateEmbeddedTlb()
.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())
Expand All @@ -74,13 +98,14 @@ public SharedTestState()
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,
Expand All @@ -93,24 +118,43 @@ public SharedTestState()
}
}

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);
}
}
}
Expand Down

0 comments on commit 78083e7

Please sign in to comment.