Skip to content

Commit

Permalink
Use HostApiInvokerApp for BundleProbe test (remove `BundleProbeTe…
Browse files Browse the repository at this point in the history
…ster` app) (#91636)

- Use `HostApiInvokerApp` / host runtime contract instead of a separate app for testing the bundle probe
- Make test app take arguments of what to probe and output result (that test case validates) instead of having the logic itself
- Remove `BundleProbeTester` app
  • Loading branch information
elinor-fung authored Sep 6, 2023
1 parent 9c4b135 commit 76d17b2
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 127 deletions.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>$(TestTargetRid)</RuntimeIdentifier>
<RuntimeFrameworkVersion>$(MNAVersion)</RuntimeFrameworkVersion>
<DefineConstants Condition="'$(OS)' == 'Windows_NT'">WINDOWS;$(DefineConstants)</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal struct host_runtime_contract
public nint size;
public void* context;
public delegate* unmanaged[Stdcall]<byte*, byte*, nint, void*, nint> get_runtime_property;
public IntPtr bundle_probe;
public delegate* unmanaged[Stdcall]<byte*, nint, nint, nint, byte> bundle_probe;
public IntPtr pinvoke_override;
}

Expand Down Expand Up @@ -68,12 +68,52 @@ static string GetProperty(string name, host_runtime_contract contract)
}
}

public static void Test_bundle_probe(string[] args)
{
host_runtime_contract contract = GetContract();
if (contract.bundle_probe == null)
{
Console.WriteLine("host_runtime_contract.bundle_probe is not set");
return;
}

bool success = true;
foreach (string path in args)
{
Probe(contract, path);
}

unsafe static void Probe(host_runtime_contract contract, string path)
{
Span<byte> pathSpan = stackalloc byte[Encoding.UTF8.GetMaxByteCount(path.Length)];
byte* pathPtr = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(pathSpan));
int pathLen = Encoding.UTF8.GetBytes(path, pathSpan);
pathSpan[pathLen] = 0;

Int64 size, offset, compressedSize;
bool exists = contract.bundle_probe(pathPtr, (IntPtr)(&offset), (IntPtr)(&size), (IntPtr)(&compressedSize)) != 0;

Console.WriteLine($"{nameof(host_runtime_contract.get_runtime_property)}: {path} - found = {exists}");
if (exists)
{
if (compressedSize < 0 || compressedSize > size)
throw new Exception($"Invalid compressedSize obtained for {path} within bundle.");

if (size <= 0 || offset <= 0)
throw new Exception($"Invalid location obtained for {path} within bundle.");
}
}
}

public static bool RunTest(string apiToTest, string[] args)
{
switch (apiToTest)
{
case $"{nameof(host_runtime_contract)}.{nameof(host_runtime_contract.get_runtime_property)}":
Test_get_runtime_property(args);
Test_get_runtime_property(args[1..]);
break;
case $"{nameof(host_runtime_contract)}.{nameof(host_runtime_contract.bundle_probe)}":
Test_bundle_probe(args[1..]);
break;
default:
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Linq;
using BundleTests.Helpers;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.CoreSetup.Test;
Expand All @@ -19,35 +20,45 @@ public BundleProbe(SharedTestState fixture)
}

[Fact]
private void Bundle_Probe_Not_Passed_For_Non_Single_File_App()
private void NonSingleFileApp_NoProbe()
{
var fixture = sharedTestState.TestFixture.Copy();
string appExe = BundleHelper.GetHostPath(fixture);

Command.Create(appExe)
Command.Create(appExe, "host_runtime_contract.bundle_probe")
.CaptureStdErr()
.CaptureStdOut()
.Execute()
.Should()
.Pass()
.And
.HaveStdOutContaining("No BUNDLE_PROBE");
.Should().Pass()
.And.HaveStdOutContaining("host_runtime_contract.bundle_probe is not set");
}

[Fact]
private void Bundle_Probe_Passed_For_Single_File_App()
private void SingleFileApp_ProbeFiles()
{
var fixture = sharedTestState.TestFixture.Copy();
string singleFile = BundleSelfContainedApp(fixture);

Command.Create(singleFile, "SingleFile")
(string Path, bool ShouldBeFound)[] itemsToProbe = new[]
{
($"{fixture.TestProject.AssemblyName}.dll", true),
($"{fixture.TestProject.AssemblyName}.runtimeconfig.json", true),
("System.Private.CoreLib.dll", true),
("hostpolicy.dll", false),
("--", false),
(string.Empty, false),
};

var result = Command.Create(singleFile, $"host_runtime_contract.bundle_probe {string.Join(" ", itemsToProbe.Select(i => i.Path))}")
.CaptureStdErr()
.CaptureStdOut()
.Execute()
.Should()
.Pass()
.And
.HaveStdOutContaining("BUNDLE_PROBE OK");
.Execute();

result.Should().Pass();
foreach (var item in itemsToProbe)
{
result.Should().HaveStdOutContaining($"{item.Path} - found = {item.ShouldBeFound}");
}
}

public class SharedTestState : SharedTestStateBase, IDisposable
Expand All @@ -56,7 +67,7 @@ public class SharedTestState : SharedTestStateBase, IDisposable

public SharedTestState()
{
TestFixture = PreparePublishedSelfContainedTestProject("BundleProbeTester");
TestFixture = PreparePublishedSelfContainedTestProject("HostApiInvokerApp");
}

public void Dispose()
Expand Down

0 comments on commit 76d17b2

Please sign in to comment.