Skip to content

Commit

Permalink
[tests] Add MonoApi runtime tests (#65221)
Browse files Browse the repository at this point in the history
Contributes to #64456

Create a new directory src/tests/Interop/MonoAPI for tests that use the mono embedding API.

Move the mono libtest.c native library along with managed tests: InstallEHCallback.cs, PInvokeDetach.cs and Thunks.cs to src/tests/Interop/MonoAPI/...

The native library (now called mono-embedding-api-test.c) builds on all platforms where we build native support libraries for the runtime tests.

The managed tests only run on desktop mono configurations for now.


* copy libtest.c from mono to src/tests and add cmake builds

* Make it build with the monoapi project

* remove mono-compiler.h dependency

* Remove dependency on gmodule.h

   Had to copy the w32_find_symbol code that searches for a symbol in every module.

* Remove test library eglib dependency

   Delete some unrunnable tests.

   Copy some basic eglib utilities into the test.

* Move native embedding API test lib to Interop/MonoAPI/Native

* Move install_eh_callback test to src/tests/Interop/MonoAPI/MonoMono

* add issues.targets excludes for MonoAPI tests

  Not expected to run on coreclr or mono on wasm or mobile, for now.

* Add PInvokeDetach MonoAPI test

* Return exit code 100 on success

* Change test class names to be unique

* fix win32 and gcc builds

* simplify managed code

* put all the MonoMono tests in a single directory

* Use the new MONO_API_FUNCTION monoapi headers

* compile the native library as C, not C++, same as libtest.c in the past

* delete many unused test functions

* delete unused utilities

* Add Thunks.cs tests

* Use a common setup method to probe for symbols

* simplify the native test library

* Make the PInvokeDetach native code sleep less

* add MIT banner

* skip Thunks test on AOT

   In the mono/mono repo that test was not expected to work with AOT
  • Loading branch information
lambdageek committed Mar 4, 2022
1 parent 9053aa1 commit 483b8f2
Show file tree
Hide file tree
Showing 15 changed files with 1,299 additions and 18 deletions.
1 change: 1 addition & 0 deletions src/tests/Interop/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ add_subdirectory(ICustomMarshaler/Primitives)
add_subdirectory(LayoutClass)
add_subdirectory(PInvoke/DateTime)
add_subdirectory(DisabledRuntimeMarshalling)
add_subdirectory(MonoAPI/Native)
if(CLR_CMAKE_TARGET_WIN32)
add_subdirectory(ExecInDefAppDom)
add_subdirectory(MarshalAPI/IUnknown)
Expand Down
35 changes: 35 additions & 0 deletions src/tests/Interop/MonoAPI/Common/MonoAPISupport.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
using System;
using System.Runtime.InteropServices;

namespace MonoAPI.Tests;

public class MonoAPISupport
{
public const string TestLibName = "mono-embedding-api-test";

[DllImport(TestLibName)]
private static extern byte libtest_initialize_runtime_symbols(IntPtr libcoreclr_name);

public static void Setup()
{
string libName = TestLibrary.XPlatformUtils.GetStandardNativeLibraryFileName("coreclr");
if (!SetupSymbols(libName))
throw new Exception ($"Native library could not probe for runtime embedding API symbols in {libName}");
}

private static bool SetupSymbols(string libName)
{
IntPtr ptr = IntPtr.Zero;
byte res = 0;
try {
ptr = Marshal.StringToHGlobalAnsi(libName);
res = libtest_initialize_runtime_symbols(ptr);
} finally {
Marshal.FreeHGlobal(ptr);
}
return res != 0;
}
}
7 changes: 7 additions & 0 deletions src/tests/Interop/MonoAPI/MonoMono/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\Directory.Build.props" />

<ItemGroup>
<ProjectReference Include="$(TestSourceDir)Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

namespace MonoAPI.Tests.MonoMono.InstallEHCallback;

public class MonoPInvokeCallbackAttribute : Attribute {
public MonoPInvokeCallbackAttribute (Type delegateType) { }
}

public class Tests {
public class InstallEHCallback {

[DllImport ("libtest")]
[DllImport (MonoAPISupport.TestLibName)]
public static extern void mono_test_setjmp_and_call (VoidVoidDelegate del, out IntPtr handle);

[DllImport ("libtest")]
[DllImport (MonoAPISupport.TestLibName)]
public static extern void mono_test_setup_ftnptr_eh_callback (VoidVoidDelegate del, VoidHandleHandleOutDelegate inside_eh_callback);

[DllImport ("libtest")]
[DllImport (MonoAPISupport.TestLibName)]
public static extern void mono_test_cleanup_ftptr_eh_callback ();

public delegate void VoidVoidDelegate ();
Expand Down Expand Up @@ -168,6 +173,15 @@ public static int test_0_throw_and_raise_exception ()

static int Main ()
{
return TestDriver.RunTests (typeof (Tests));
MonoAPI.Tests.MonoAPISupport.Setup();
int result;
result = test_0_setjmp_exn_handler ();
if (result != 0)
return 100 + result;
result = test_0_throw_and_raise_exception ();
if (result != 0)
return 100 + result;
return 100;
}
}

13 changes: 13 additions & 0 deletions src/tests/Interop/MonoAPI/MonoMono/InstallEHCallback.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
<Compile Include="..\Common\*.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Native\mono-embedding-api-test\CMakeLists.txt" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
//
// pinvoke-detach-1.cs:
//
Expand All @@ -7,14 +10,33 @@
using System.Threading;
using System.Runtime.InteropServices;

namespace MonoAPI.Tests.MonoMono.PInvokeDetach;

public class MonoPInvokeCallbackAttribute : Attribute {
public MonoPInvokeCallbackAttribute (Type delegateType) { }
}

public class Tests {
public class PInvokeDetach {
const string TestNamespace = "MonoAPI.Tests.MonoMono.PInvokeDetach";
const string TestName = nameof (PInvokeDetach);

public static int Main ()
{
return TestDriver.RunTests (typeof (Tests));
MonoAPI.Tests.MonoAPISupport.Setup();
int result;
result = test_0_attach_invoke_foreign_thread ();
if (result != 0)
return 100 + result;
result = test_0_attach_invoke_foreign_thread_delegate ();
if (result != 0)
return 100 + result;
result = test_0_attach_invoke_block_foreign_thread ();
if (result != 0)
return 100 + result;
result = test_0_attach_invoke_block_foreign_thread_delegate ();
if (result != 0)
return 100 + result;
return 100;
}

public delegate void VoidVoidDelegate ();
Expand All @@ -27,13 +49,13 @@ private static void MethodInvokedFromNative ()
was_called++;
}

[DllImport ("libtest", EntryPoint="mono_test_attach_invoke_foreign_thread")]
[DllImport (MonoAPISupport.TestLibName, EntryPoint="mono_test_attach_invoke_foreign_thread")]
public static extern bool mono_test_attach_invoke_foreign_thread (string assm_name, string name_space, string class_name, string method_name, VoidVoidDelegate del);

public static int test_0_attach_invoke_foreign_thread ()
{
was_called = 0;
bool skipped = mono_test_attach_invoke_foreign_thread (typeof (Tests).Assembly.Location, "", "Tests", "MethodInvokedFromNative", null);
bool skipped = mono_test_attach_invoke_foreign_thread (typeof (PInvokeDetach).Assembly.Location, TestNamespace, TestName, nameof(MethodInvokedFromNative), null);
GC.Collect (); // should not hang waiting for the foreign thread
return skipped || was_called == 5 ? 0 : 1;
}
Expand All @@ -60,12 +82,12 @@ private static void MethodInvokedFromNative2 ()
{
}

[DllImport ("libtest", EntryPoint="mono_test_attach_invoke_block_foreign_thread")]
[DllImport (MonoAPISupport.TestLibName, EntryPoint="mono_test_attach_invoke_block_foreign_thread")]
public static extern bool mono_test_attach_invoke_block_foreign_thread (string assm_name, string name_space, string class_name, string method_name, VoidVoidDelegate del);

public static int test_0_attach_invoke_block_foreign_thread ()
{
bool skipped = mono_test_attach_invoke_block_foreign_thread (typeof (Tests).Assembly.Location, "", "Tests", "MethodInvokedFromNative2", null);
bool skipped = mono_test_attach_invoke_block_foreign_thread (typeof (PInvokeDetach).Assembly.Location, TestNamespace, TestName, nameof(MethodInvokedFromNative2), null);
GC.Collect (); // should not hang waiting for the foreign thread
return 0; // really we succeed if the app can shut down without hanging
}
Expand Down
13 changes: 13 additions & 0 deletions src/tests/Interop/MonoAPI/MonoMono/PInvokeDetach.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
<Compile Include="..\Common\*.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Native\mono-embedding-api-test\CMakeLists.txt" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
using System;
using System.Reflection;
using System.Runtime.InteropServices;

public class Test
namespace MonoAPI.Tests.MonoMono.Thunks;

public class Thunks
{
[DllImport ("libtest")]
[DllImport (MonoAPISupport.TestLibName)]
public static extern int test_method_thunk (int test_id, IntPtr testMethodHandle,
IntPtr createObjectHandle);

Expand All @@ -31,14 +36,15 @@ static void RunTests(int series, Type type)

public static int Main ()
{
RunTests (0, typeof (Test));
MonoAPI.Tests.MonoAPISupport.Setup();
RunTests (0, typeof (Thunks));
RunTests (100, typeof (TestStruct));
return 0;
return 100;
}

public static object CreateObject ()
{
return new Test ();
return new Thunks ();
}

public static void Test0 ()
Expand Down Expand Up @@ -102,9 +108,9 @@ public static void Test9 (ref byte a1, ref short a2, ref int a3, ref long a4, re
throw new NotImplementedException ();
}

public static void Test10 (ref Test obj)
public static void Test10 (ref Thunks obj)
{
obj = new Test ();
obj = new Thunks ();
}
}

Expand Down
13 changes: 13 additions & 0 deletions src/tests/Interop/MonoAPI/MonoMono/Thunks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
<Compile Include="..\Common\*.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Native\mono-embedding-api-test\CMakeLists.txt" />
</ItemGroup>
</Project>
2 changes: 2 additions & 0 deletions src/tests/Interop/MonoAPI/Native/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

add_subdirectory(mono-embedding-api-test)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 3.13.0)
project (MonoEmbeddingApiTest)
include_directories(${INC_PLATFORM_DIR})


add_subdirectory(${CLR_SRC_NATIVE_DIR}/public public_api)

# add the library
add_library (mono-embedding-api-test SHARED mono-embedding-api-test.c api-types.h api-functions.h)
target_link_libraries(mono-embedding-api-test monoapi ${LINK_LIBRARIES_ADDITIONAL})

if(CLR_CMAKE_HOST_OSX)
target_compile_definitions(mono-embedding-api-test PRIVATE -DHOST_DARWIN)
elseif(CLR_CMAKE_HOST_WIN32)
target_compile_definitions(mono-embedding-api-test PRIVATE -DHOST_WIN32 -D_CRT_SECURE_NO_WARNINGS)
else()
target_compile_definitions(mono-embedding-api-test PRIVATE -DHOST_LINUX)
endif()

# add the install targets
install (TARGETS mono-embedding-api-test DESTINATION bin)

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
// This file intentionally doesn't have header guards
#include <mono/metadata/details/appdomain-functions.h>
#include <mono/metadata/details/assembly-functions.h>
#include <mono/metadata/details/class-functions.h>
#include <mono/metadata/details/threads-functions.h>
#include <mono/metadata/details/object-functions.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//

#ifndef TEST_EMBEDDING_API_TYPES_H
#define TEST_EMBEDDING_API_TYPES_H

#include <mono/utils/details/mono-publib-types.h>
#include <mono/metadata/details/class-types.h>
#include <mono/metadata/details/object-types.h>
#include <mono/metadata/details/appdomain-types.h>
#include <mono/metadata/details/assembly-types.h>
#include <mono/metadata/details/threads-types.h>

MONO_BEGIN_DECLS



MONO_END_DECLS

#endif /*TEST_EMBEDDING_API_TYPES_H*/
Loading

0 comments on commit 483b8f2

Please sign in to comment.