Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build C++/CLI tests as .NET Core C++/CLI #56502

Merged
6 commits merged into from
Aug 2, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docs/workflow/testing/coreclr/windows-test-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,22 @@ By default, the test build uses Release as the libraries configuration. To use a
src\tests\build.cmd /p:LibrariesConfiguration=Debug
```

## Building Native Test Components

Sometimes you want to only build the native test components instead of the managed and native components. To build the native test components only, pass the `skipmanaged` and `skipgeneratelayout` parameters to the build script as follows:

```
src\tests\build.cmd skipmanaged skipgeneratelayout
```

## Building C++/CLI native test components against the live ref assemblies

By default, the C++/CLI native test components build against the ref pack from the SDK specified in the `global.json` file in the root of the repository. To build these components against the ref assemblies produced in the build, pass the `-cmakeargs -DCPP_CLI_LIVE_REF_ASSEMBLIES=1` parameters to the test build. For example:

```
src\tests\build.cmd skipmanaged -cmakeargs -DCPP_CLI_LIVE_REF_ASSEMBLIES=1
```

## Building Precompiled Tests

```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ static int Main(string[] args)

try
{
Assembly ijwNativeDll = IjwHelper.LoadIjwAssembly("IjwCopyConstructorMarshaler");
Assembly ijwNativeDll = Assembly.Load("IjwCopyConstructorMarshaler");
Type testType = ijwNativeDll.GetType("TestClass");
object testInstance = Activator.CreateInstance(testType);
MethodInfo testMethod = testType.GetMethod("PInvokeNumCopies");
Expand All @@ -33,7 +33,7 @@ static int Main(string[] args)
// Reverse PInvoke will copy 3 times. Two are from the same paths as the PInvoke,
// and the third is from the reverse P/Invoke call.
Assert.AreEqual(3, (int)testMethod.Invoke(testInstance, null));

testMethod = testType.GetMethod("PInvokeNumCopiesDerivedType");

// PInvoke will copy twice. Once from argument to parameter, and once from the managed to native parameter.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="CopyConstructorMarshaler.cs" />
<Compile Include="../IjwHelper.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="CMakeLists.txt" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,15 @@ static int Main(string[] args)

try
{
// Load a fake mscoree.dll to avoid starting desktop
IntPtr ijwHost = NativeLibrary.Load(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "mscoree.dll"));
IntPtr ijwHost = NativeLibrary.Load(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ijwhost.dll"));

WasModuleVTableQueriedDelegate wasModuleVTableQueried = Marshal.GetDelegateForFunctionPointer<WasModuleVTableQueriedDelegate>(NativeLibrary.GetExport(ijwHost, "WasModuleVTableQueried"));

// Load IJW via reflection
Assembly.Load("IjwNativeDll");

IntPtr ijwModuleHandle = GetModuleHandle("IjwNativeDll.dll");

Assert.AreNotEqual(IntPtr.Zero, ijwModuleHandle);
Assert.IsTrue(wasModuleVTableQueried(ijwModuleHandle));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="FixupCallsHostWhenLoaded.cs" />
<Compile Include="../IjwHelper.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../IjwNativeDll/CMakeLists.txt" />
Expand Down
30 changes: 29 additions & 1 deletion src/tests/Interop/IJW/IJW.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ if (CLR_CMAKE_HOST_WIN32)
add_compile_options(/wd4365)

# IJW
add_compile_options(/clr)
add_compile_options(/clr:netcore)

# IJW requires the CRT as a dll, not linked in
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:Debug>DLL)
Expand All @@ -27,4 +27,32 @@ if (CLR_CMAKE_HOST_WIN32)
string(REPLACE "/GR-" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()

set(CLR_SDK_REF_PACK "")
set(CLR_SDK_REF_PACK_DISCOVERY_ERROR "")
set(CLR_SDK_REF_PACK_DISCOVERY_RESULT 0)

if (CPP_CLI_LIVE_REF_ASSEMBLIES)
message("Using live-built ref assemblies for C++/CLI runtime tests.")
execute_process(
COMMAND powershell -ExecutionPolicy ByPass -NoProfile "${CMAKE_CURRENT_LIST_DIR}/getRefPackFolderFromArtifacts.ps1"
OUTPUT_VARIABLE CLR_SDK_REF_PACK
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_VARIABLE CLR_SDK_REF_PACK_DISCOVERY_ERROR
RESULT_VARIABLE CLR_SDK_REF_PACK_DISCOVERY_RESULT)
else()
execute_process(
COMMAND powershell -ExecutionPolicy ByPass -NoProfile "${CMAKE_CURRENT_LIST_DIR}/getRefPackFolderFromSdk.ps1"
OUTPUT_VARIABLE CLR_SDK_REF_PACK
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_VARIABLE CLR_SDK_REF_PACK_DISCOVERY_ERROR
RESULT_VARIABLE CLR_SDK_REF_PACK_DISCOVERY_RESULT)
endif()

if (NOT CLR_SDK_REF_PACK_DISCOVERY_RESULT EQUAL 0)
message(FATAL_ERROR "Unable to find reference assemblies: ${CLR_SDK_REF_PACK_DISCOVERY_ERROR}")
endif()

add_compile_options(/AI${CLR_SDK_REF_PACK})

list(APPEND LINK_LIBRARIES_ADDITIONAL ijwhost)
endif()
21 changes: 0 additions & 21 deletions src/tests/Interop/IJW/IjwHelper.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ unsafe static int Main(string[] args)
{
HostPolicyMock.Initialize(Environment.CurrentDirectory, null);

// Load our fake mscoree to prevent .NET Framework from loading.
NativeLibrary.Load(Path.Combine(Environment.CurrentDirectory, "mscoree.dll"));

Console.WriteLine("Verify that we can load an IJW assembly from native code.");
string ijwModulePath = Path.Combine(Environment.CurrentDirectory, "IjwNativeCallingManagedDll.dll");
IntPtr ijwNativeHandle = NativeLibrary.Load(ijwModulePath);
Expand All @@ -42,7 +39,7 @@ unsafe static int Main(string[] args)
{
InMemoryAssemblyLoader.LoadInMemoryAssembly(ijwNativeHandle, (IntPtr)path);
}

NativeEntryPointDelegate nativeEntryPoint = Marshal.GetDelegateForFunctionPointer<NativeEntryPointDelegate>(NativeLibrary.GetExport(ijwNativeHandle, "NativeEntryPoint"));

Assert.AreEqual(100, nativeEntryPoint());
Expand All @@ -63,7 +60,7 @@ unsafe static int Main(string[] args)
changeReturnedValueMethod.Invoke(null, new object[] { newValue });

Assert.AreEqual(newValue, (int)getReturnValueMethod.Invoke(null, null));

// Native images are only loaded into memory once. As a result, the stubs in the vtfixup table
// will always point to JIT stubs that exist in the first ALC that the module was loaded into.
// As a result, if an IJW module is loaded into two different ALCs, or if the module is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ static int Main(string[] args)
}

bool success = true;
Assembly ijwNativeDll = IjwHelper.LoadIjwAssembly("IjwNativeDll");
Assembly ijwNativeDll = Assembly.Load("IjwNativeDll");

TestFramework.BeginTestCase("Call native method returning int");
Type testType = ijwNativeDll.GetType("TestClass");
Expand All @@ -45,19 +45,7 @@ static int Main(string[] args)
catch { }
TestFramework.EndTestCase();

TestFramework.BeginTestCase("Ensure .NET Framework was not loaded");
IntPtr clrHandle = GetModuleHandle("mscoreei.dll");
if (clrHandle != IntPtr.Zero)
{
TestFramework.LogError("IJW", ".NET Framework loaded by IJw module load");
success = false;
}
TestFramework.EndTestCase();

return success ? 100 : 99;
}

[DllImport("kernel32.dll")]
static extern IntPtr GetModuleHandle(string lpModuleName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="ManagedCallingNative.cs" />
<Compile Include="../IjwHelper.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../IjwNativeDll/CMakeLists.txt" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ static int Main(string[] args)
}

bool success = true;
Assembly ijwNativeDll = IjwHelper.LoadIjwAssembly("IjwNativeCallingManagedDll");
Assembly ijwNativeDll = Assembly.Load("IjwNativeCallingManagedDll");

TestFramework.BeginTestCase("Call native method returning int");
Type testType = ijwNativeDll.GetType("TestClass");
Expand All @@ -34,19 +34,7 @@ static int Main(string[] args)
}
TestFramework.EndTestCase();

TestFramework.BeginTestCase("Ensure .NET Framework was not loaded");
IntPtr clrHandle = GetModuleHandle("mscoreei.dll");
if (clrHandle != IntPtr.Zero)
{
TestFramework.LogError("IJW", ".NET Framework loaded by IJw module load");
success = false;
}
TestFramework.EndTestCase();

return success ? 100 : 99;
}

[DllImport("kernel32.dll")]
static extern IntPtr GetModuleHandle(string lpModuleName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="NativeCallingManaged.cs" />
<Compile Include="../IjwHelper.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../IjwNativeCallingManagedDll/CMakeLists.txt" />
Expand Down
3 changes: 2 additions & 1 deletion src/tests/Interop/IJW/NativeVarargs/IjwNativeVarargs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
#include <array>
#include <functional>
#include <iostream>
#using <mscorlib.dll>
#using <System.Runtime.dll>
#using <System.Collections.dll>
using namespace System::Collections::Generic;

public enum class TestCases
Expand Down
2 changes: 1 addition & 1 deletion src/tests/Interop/IJW/NativeVarargs/NativeVarargsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static int Main(string[] args)

try
{
Assembly ijwNativeDll = IjwHelper.LoadIjwAssembly("IjwNativeVarargs");
Assembly ijwNativeDll = Assembly.Load("IjwNativeVarargs");
Type testType = ijwNativeDll.GetType("TestClass");
object testInstance = Activator.CreateInstance(testType);
MethodInfo testMethod = testType.GetMethod("RunTests");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="NativeVarargsTest.cs" />
<Compile Include="../IjwHelper.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="CMakeLists.txt" />
Expand Down
21 changes: 21 additions & 0 deletions src/tests/Interop/IJW/getRefPackFolderFromArtifacts.ps1
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.
$interopFolder = Split-Path $PSScriptRoot -Parent
$testsFolder = Split-Path $interopFolder -Parent
$srcFolder = Split-Path $testsFolder -Parent
$repoRoot = Split-Path $srcFolder -Parent

$versionPropsFile = "$repoRoot/eng/Versions.props"

$majorVersion = Select-Xml -Path $versionPropsFile -XPath "/Project/PropertyGroup/MajorVersion" | %{$_.Node.InnerText}
$minorVersion = Select-Xml -Path $versionPropsFile -XPath "/Project/PropertyGroup/MinorVersion" | %{$_.Node.InnerText}

$refPackPath = "$repoRoot/artifacts/bin/ref/net$majorVersion.$minorVersion"

if (-not (Test-Path $refPackPath))
{
Write-Error "Reference assemblies not found in the artifacts folder. Did you build the libs.ref subset? Did the repo layout change?"
jkoritzinsky marked this conversation as resolved.
Show resolved Hide resolved
return 1
}

Write-Output $refPackPath
28 changes: 28 additions & 0 deletions src/tests/Interop/IJW/getRefPackFolderFromSdk.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Licensed to the .NET Foundation under one or more agreements.
# The .NET Foundation licenses this file to you under the MIT license.
$interopFolder = Split-Path $PSScriptRoot -Parent
$testsFolder = Split-Path $interopFolder -Parent
$srcFolder = Split-Path $testsFolder -Parent
$repoRoot = Split-Path $srcFolder -Parent


. "$repoRoot/eng/common/tools.ps1"

$dotnetRoot = InitializeDotNetCli $true $false

$dotnetSdkVersion = $GlobalJson.tools.dotnet

$sdkBundledVersionsFile = "$dotnetRoot/sdk/$dotnetSdkVersion/Microsoft.NETCoreSdk.BundledVersions.props"

$refPackVersion = Select-Xml -Path $sdkBundledVersionsFile -XPath "/Project/PropertyGroup/BundledNETCoreAppPackageVersion" | %{$_.Node.InnerText}
$refPackTfmVersion = Select-Xml -Path $sdkBundledVersionsFile -XPath "/Project/PropertyGroup/BundledNETCoreAppTargetFrameworkVersion" | %{$_.Node.InnerText}

$refPackPath = "$dotnetRoot/packs/Microsoft.NETCore.App.Ref/$refPackVersion/ref/net$refPackTfmVersion"

if (-not (Test-Path $refPackPath))
{
Write-Error "Reference assemblies not found in the SDK folder. Did the SDK layout change? Did the SDK change how it describes the bundled runtime version?"
return 1
}

Write-Output $refPackPath
8 changes: 4 additions & 4 deletions src/tests/Interop/IJW/ijwhostmock/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
project (mscoree)
include_directories( ${INC_PLATFORM_DIR} )
set(SOURCES mscoree.cpp)
set(SOURCES ijwhost.cpp)

# add the shared library
add_library (mscoree SHARED ${SOURCES})
target_link_libraries(mscoree ${LINK_LIBRARIES_ADDITIONAL})
add_library (ijwhost SHARED ${SOURCES})
target_link_libraries(ijwhost ${LINK_LIBRARIES_ADDITIONAL})

# add the install targets
install (TARGETS mscoree DESTINATION bin)
install (TARGETS ijwhost DESTINATION bin)
5 changes: 3 additions & 2 deletions src/tests/build.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ set __CopyNativeProjectsAfterCombinedTestBuild=true
set __SkipGenerateLayout=0
set __GenerateLayoutOnly=0
set __Ninja=1
set __CMakeArgs=

@REM CMD has a nasty habit of eating "=" on the argument list, so passing:
@REM -priority=1
Expand Down Expand Up @@ -97,7 +98,7 @@ if /i "%1" == "skipgeneratelayout" (set __SkipGenerateLayout=1&set processedA
if /i "%1" == "copynativeonly" (set __CopyNativeTestBinaries=1&set __SkipNative=1&set __CopyNativeProjectsAfterCombinedTestBuild=false&set __SkipGenerateLayout=1&set __SkipTestWrappers=1&set __SkipCrossgenFramework=1&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "generatelayoutonly" (set __SkipManaged=1&set __SkipNative=1&set __CopyNativeProjectsAfterCombinedTestBuild=false&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "buildtestwrappersonly" (set __SkipNative=1&set __SkipManaged=1&set __BuildTestWrappersOnly=1&set __SkipGenerateLayout=1&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)

if /i "%1" == "-cmakeargs" (set __CMakeArgs="%2=%3" %__CMakeArgs%&set "processedArgs=!processedArgs! %1 %2=%3"&shift&shift&goto Arg_Loop)
if /i "%1" == "-msbuild" (set __Ninja=0&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "buildagainstpackages" (echo error: Remove /BuildAgainstPackages switch&&exit /b1)
if /i "%1" == "crossgen2" (set __DoCrossgen2=1&set __TestBuildMode=crossgen2&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
Expand Down Expand Up @@ -220,7 +221,7 @@ if %__Ninja% EQU 1 (
) else (
set __ExtraCmakeArgs="-DCMAKE_SYSTEM_VERSION=10.0"
)
call "%__RepoRootDir%\eng\native\gen-buildsys.cmd" "%__ProjectFilesDir%" "%__NativeTestIntermediatesDir%" %__VSVersion% %__BuildArch% !__ExtraCmakeArgs!
call "%__RepoRootDir%\eng\native\gen-buildsys.cmd" "%__ProjectFilesDir%" "%__NativeTestIntermediatesDir%" %__VSVersion% %__BuildArch% !__ExtraCmakeArgs! !__CMakeArgs!

if not !errorlevel! == 0 (
echo %__ErrMsgPrefix%%__MsgPrefix%Error: failed to generate native component build project!
Expand Down