summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/CoreFX/CoreFX.issues.json84
-rw-r--r--tests/issues.targets89
-rw-r--r--tests/runtest.cmd28
-rwxr-xr-xtests/runtest.py105
-rwxr-xr-xtests/runtest.sh14
-rw-r--r--tests/src/Common/Platform/platformdefines.cpp592
-rw-r--r--tests/src/Common/Platform/platformdefines.h42
-rw-r--r--tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp2
-rw-r--r--tests/src/Interop/CMakeLists.txt2
-rw-r--r--tests/src/Interop/StringMarshalling/BSTR/BSTRTest.cs200
-rw-r--r--tests/src/Interop/StringMarshalling/BSTR/BSTRTest.csproj41
-rw-r--r--tests/src/Interop/StringMarshalling/BSTR/BSTRTestNative.cpp164
-rw-r--r--tests/src/Interop/StringMarshalling/BSTR/CMakeLists.txt18
-rw-r--r--tests/src/Interop/StringMarshalling/BSTR/PinvokeDef.cs53
-rwxr-xr-xtests/src/Interop/common/types.h4
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_20260/GitHub_20260.cs48
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_20260/GitHub_20260.csproj34
-rw-r--r--tests/src/Regressions/coreclr/16775/sharedinterfacemethod.il91
-rw-r--r--tests/src/Regressions/coreclr/16775/sharedinterfacemethod.ilproj35
-rw-r--r--tests/src/dir.props1
-rw-r--r--tests/src/tracing/tracecontrol/TraceControl.cs113
-rw-r--r--tests/src/tracing/tracecontrol/tracecontrol.csproj29
22 files changed, 1528 insertions, 261 deletions
diff --git a/tests/CoreFX/CoreFX.issues.json b/tests/CoreFX/CoreFX.issues.json
index 9398076e62..35fe2d5d61 100644
--- a/tests/CoreFX/CoreFX.issues.json
+++ b/tests/CoreFX/CoreFX.issues.json
@@ -455,5 +455,89 @@
"classes": null,
"methods": null
}
+ },
+ {
+ "name": "Microsoft.VisualBasic.Tests",
+ "enabled": true,
+ "exclusions": {
+ "namespaces": null,
+ "classes": null,
+ "methods": [
+ {
+ "name" : "Microsoft.VisualBasic.Tests.ConversionsTests.ToChar_InvalidObject_ThrowsInvalidCastException",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "Microsoft.VisualBasic.Tests.ConversionsTests.ToSingle_InvalidObject_ThrowsInvalidCastException",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "Microsoft.VisualBasic.Tests.ConversionsTests.ToBoolean_InvalidObject_ThrowsInvalidCastException",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "Microsoft.VisualBasic.Tests.ConversionsTests.ToSByte_InvalidObject_ThrowsInvalidCastException",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "Microsoft.VisualBasic.Tests.ConversionsTests.ToDouble_InvalidObject_ThrowsInvalidCastException",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "Microsoft.VisualBasic.Tests.ConversionsTests.ToDecimal_InvalidObject_ThrowsInvalidCastException",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "Microsoft.VisualBasic.Tests.ConversionsTests.ToByte_InvalidObject_ThrowsInvalidCastException",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "Microsoft.VisualBasic.Tests.ConversionsTests.ToLong_InvalidObject_ThrowsInvalidCastException",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "Microsoft.VisualBasic.Tests.ConversionsTests.ToUShort_InvalidObject_ThrowsInvalidCastException",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "Microsoft.VisualBasic.Tests.ConversionsTests.ToUInteger_InvalidObject_ThrowsInvalidCastException",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "Microsoft.VisualBasic.Tests.ConversionsTests.ToInteger_InvalidObject_ThrowsInvalidCastException",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "Microsoft.VisualBasic.Tests.ConversionsTests.ToShort_InvalidObject_ThrowsInvalidCastException",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "Microsoft.VisualBasic.Tests.ConversionsTests.ToULong_InvalidObject_ThrowsInvalidCastException",
+ "reason" : "outdated"
+ }
+ ]
+ }
+ },
+ {
+ "name": "System.Numerics.Vectors.Tests",
+ "enabled": true,
+ "exclusions": {
+ "namespaces": null,
+ "classes": null,
+ "methods": [
+ {
+ "name" : "System.Numerics.Tests.Vector2Tests.Vector2ClampTest",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "System.Numerics.Tests.Vector3Tests.Vector3ClampTest",
+ "reason" : "outdated"
+ },
+ {
+ "name" : "System.Numerics.Tests.Vector4Tests.Vector4ClampTest",
+ "reason" : "outdated"
+ }
+ ]
+ }
}
]
diff --git a/tests/issues.targets b/tests/issues.targets
index 3ff8ff3611..1c1ca62504 100644
--- a/tests/issues.targets
+++ b/tests/issues.targets
@@ -245,6 +245,12 @@
</ExcludeList>
</ItemGroup>
+ <ItemGroup Condition="'$(XunitTestBinBase)' != '' and '$(TargetsWindows)' == 'true'">
+ <ExcludeList Include="$(XunitTestBinBase)/tracing/tracecontrol/tracecontrol/*">
+ <Issue>Unable to write config file to app location</Issue>
+ </ExcludeList>
+ </ItemGroup>
+
<!-- Windows x64 specific excludes -->
<ItemGroup Condition="'$(XunitTestBinBase)' != '' and '$(BuildArch)' == 'x64' and '$(TargetsWindows)' == 'true'">
<ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest612/Generated612/*">
@@ -381,9 +387,48 @@
<ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/DefaultInterfaceMethods/diamondshape/diamondshape_r/*">
<Issue>9565</Issue>
</ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/GC/API/NoGCRegion/NoGC/*">
+ <Issue>needs triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/baseservices/varargs/varargsupport_r/*">
+ <Issue>Varargs supported on this platform</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/baseservices/varargs/varargsupport/*">
+ <Issue>Varargs supported on this platform</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/Directed/arglist/vararg/*">
+ <Issue>Needs triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/tracing/runtimeeventsource/runtimeeventsource/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/tracing/tracevalidation/inducedgc/inducedgc/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/opt/rngchk/RngchkStress3/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i53/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i13/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i03/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i33/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i63/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i73/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
</ItemGroup>
- <!-- Windows arm32 specific excludes -->
+ <!-- arm32 All OS specific excludes -->
<ItemGroup Condition="'$(XunitTestBinBase)' != '' and '$(BuildArch)' == 'arm'">
<ExcludeList Include="$(XunitTestBinBase)/JIT/Methodical/tailcall_v4/hijacking/*">
<Issue>6217</Issue>
@@ -391,6 +436,45 @@
<ExcludeList Include="$(XunitTestBinBase)/JIT/opt/Tailcall/TailcallVerifyWithPrefix/*">
<Issue>2420</Issue>
</ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/baseservices/varargs/varargsupport_r/*">
+ <Issue>Varargs supported on this platform</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/baseservices/varargs/varargsupport/*">
+ <Issue>Varargs supported on this platform</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/Directed/arglist/vararg/*">
+ <Issue>Needs triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/Interop/IJW/ManagedCallingNative/ManagedCallingNative/*">
+ <Issue>Needs triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/Interop/IJW/NativeCallingManaged/NativeCallingManaged/*">
+ <Issue>Needs triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/baseservices/exceptions/WindowsEventLog/WindowsEventLog/*">
+ <Issue>Needs triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i53/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i13/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i03/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i33/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i63/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i73/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/mcc/interop/mcc_i83/*">
+ <Issue>Needs Triage</Issue>
+ </ExcludeList>
</ItemGroup>
<!-- The following are x64 Unix failures. -->
@@ -474,6 +558,9 @@
<ExcludeList Include="$(XunitTestBinBase)/JIT/jit64/eh/FinallyExec/nonlocalexitinroot/*">
<Issue>Test times out</Issue>
</ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/JitBlue/GitHub_19361/GitHub_19361/*">
+ <Issue>20232</Issue>
+ </ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/GC/Scenarios/DoublinkList/dlstack/*">
<Issue>Release only crash</Issue>
</ExcludeList>
diff --git a/tests/runtest.cmd b/tests/runtest.cmd
index 45e722f1e7..c0991ce1ee 100644
--- a/tests/runtest.cmd
+++ b/tests/runtest.cmd
@@ -7,14 +7,18 @@ set "__MsgPrefix=RUNTEST: "
set __ThisScriptDir="%~dp0"
-call "%__ThisScriptDir%"\..\setup_vs_tools.cmd
-if NOT '%ERRORLEVEL%' == '0' exit /b 1
-
-if defined VS150COMNTOOLS (
- set __VSVersion=vs2017
-) else (
- set __VSVersion=vs2015
-)
+if /I not "%PROCESSOR_ARCHITECTURE%"=="arm64" (
+ if /I not "%PROCESSOR_ARCHITECTURE%"=="arm" (
+ call "%__ThisScriptDir%"\..\setup_vs_tools.cmd
+ if NOT '%ERRORLEVEL%' == '0' exit /b 1
+
+ if defined VS150COMNTOOLS (
+ set __VSVersion=vs2017
+ ) else (
+ set __VSVersion=vs2015
+ )
+ )
+)
:: Set the default arguments
set __BuildArch=x64
@@ -43,6 +47,7 @@ set __CoreFXTests=
set __CoreFXTestsRunAllAvailable=
set __SkipGenerateLayout=
set __BuildXUnitWrappers=
+set __PrintLastResultsOnly=
:Arg_Loop
if "%1" == "" goto ArgsDone
@@ -82,6 +87,7 @@ if /i "%1" == "ilasmroundtrip" (set __IlasmRoundTrip=1&shift&goto Arg_Loo
if /i "%1" == "GenerateLayoutOnly" (set __GenerateLayoutOnly=1&shift&goto Arg_Loop)
if /i "%1" == "skipgeneratelayout" (set __SkipGenerateLayout=1&shift&goto Arg_Loop)
if /i "%1" == "buildxunitwrappers" (set __BuildXunitWrappers=1&shift&goto Arg_Loop)
+if /i "%1" == "printlastresultsonly" (set __PrintLastResultsOnly=1&shift&goto Arg_Loop)
if /i "%1" == "PerfTests" (set __PerfTests=true&shift&goto Arg_Loop)
if /i "%1" == "CoreFXTests" (set __CoreFXTests=true&shift&goto Arg_Loop)
if /i "%1" == "CoreFXTestsAll" (set __CoreFXTests=true&set __CoreFXTestsRunAllAvailable=true&shift&goto Arg_Loop)
@@ -198,6 +204,10 @@ if defined __DoCrossgen (
set __RuntestPyArgs=%__RuntestPyArgs% --precompile_core_root
)
+if defined __PrintLastResultsOnly (
+ set __RuntestPyArgs=%__RuntestPyArgs% --analyze_results_only
+)
+
REM __ProjectDir is poorly named, it is actually <projectDir>/tests
set NEXTCMD=python "%__ProjectDir%\runtest.py" %__RuntestPyArgs%
echo !NEXTCMD!
@@ -691,6 +701,7 @@ echo VSVersion ^<vs_version^> - VS2015 or VS2017 ^(default: VS2017^).
echo TestEnv ^<test_env_script^> - Run a custom script before every test to set custom test environment settings.
echo AgainstPackages - This indicates that we are running tests that were built against packages.
echo GenerateLayoutOnly - If specified will not run the tests and will only create the Runtime Dependency Layout
+echo skipgeneratelayout - Do not generate the core root. Used for cross target testing.
echo sequential - Run tests sequentially (no parallelism).
echo crossgen - Precompile ^(crossgen^) the managed assemblies in CORE_ROOT before running the tests.
echo crossgenaltjit ^<altjit^> - Precompile ^(crossgen^) the managed assemblies in CORE_ROOT before running the tests, using the given altjit.
@@ -716,6 +727,7 @@ echo timeout ^<n^> - Sets the per-test timeout in milliseconds ^(d
echo Note: some options override this ^(gcstresslevel, longgc, gcsimulator^).
echo msbuildargs ^<args...^> - Pass all subsequent args directly to msbuild invocations.
echo ^<CORE_ROOT^> - Path to the runtime to test ^(if specified^).
+echo printlastresultsonly - Print the last test results without running tests.
echo.
echo Note that arguments are not case-sensitive.
echo.
diff --git a/tests/runtest.py b/tests/runtest.py
index 0845183690..a90a0eab99 100755
--- a/tests/runtest.py
+++ b/tests/runtest.py
@@ -560,12 +560,10 @@ def call_msbuild(coreclr_repo_location,
"""
global g_verbose
- common_msbuild_arguments = ["/nologo", "/nodeReuse:false", "/p:Platform=%s" % arch]
+ common_msbuild_arguments = []
if sequential:
- common_msbuild_arguments += ["/p:ParallelRun=false"]
- else:
- common_msbuild_arguments += ["/maxcpucount"]
+ common_msbuild_arguments += ["/p:ParallelRun=none"]
logs_dir = os.path.join(coreclr_repo_location, "bin", "Logs")
if not os.path.isdir(logs_dir):
@@ -577,6 +575,8 @@ def call_msbuild(coreclr_repo_location,
"/p:Runtests=true",
"/clp:showcommandline"]
+ command += common_msbuild_arguments
+
if is_illink:
command += ["/p:RunTestsViaIllink=true"]
@@ -671,16 +671,28 @@ def correct_line_endings(host_os, test_location, root=True):
for item in os.listdir(test_location):
correct_line_endings(host_os, os.path.join(test_location, item), False)
elif test_location.endswith(extension):
- content = None
- with open(test_location) as file_handle:
- content = file_handle.read()
-
- assert content != None
- subbed_content = content.replace(incorrect_line_ending, correct_line_ending)
+ if sys.version_info < (3,0):
+
+ content = None
+ with open(test_location) as file_handle:
+ content = file_handle.read()
+
+ assert content != None
+ subbed_content = content.replace(incorrect_line_ending, correct_line_ending)
+
+ if content != subbed_content:
+ with open(test_location, 'w') as file_handle:
+ file_handle.write(subbed_content)
- if content != subbed_content:
+ else:
+ # Python3 will correct line endings automatically.
+
+ content = None
+ with open(test_location) as file_handle:
+ content = file_handle.read()
+
with open(test_location, 'w') as file_handle:
- file_handle.write(subbed_content)
+ file_handle.write(content)
def run_tests(host_os,
arch,
@@ -866,7 +878,7 @@ def setup_args(args):
if test_location[-1] == os.path.sep:
test_location = test_location[:-1]
- if test_location != default_test_location and os.path.isdir(default_test_location):
+ if test_location.lower() != default_test_location.lower() and os.path.isdir(default_test_location):
# Remove the existing directory if there is one.
shutil.rmtree(default_test_location)
@@ -916,7 +928,20 @@ def setup_args(args):
else:
print("Core_Root: %s" % core_root)
- if host_os != "Windows_NT":
+ is_same_os = False
+ is_same_arch = False
+ is_same_build_type = False
+
+ # We will write out build information into the test directory. This is used
+ # by runtest.py to determine whether we need to rebuild the test wrappers.
+ if os.path.isfile(os.path.join(test_location, "build_info.json")):
+ with open(os.path.join(test_location, "build_info.json")) as file_handle:
+ build_info = json.load(file_handle)
+ is_same_os = build_info["build_os"] == host_os
+ is_same_arch = build_info["build_arch"] == arch
+ is_same_build_type = build_info["build_type"] == build_type
+
+ if host_os != "Windows_NT" and not (is_same_os and is_same_arch and is_same_build_type):
if test_native_bin_location is None:
print("Using default location for test_native_bin_location.")
test_native_bin_location = os.path.join(os.path.join(coreclr_repo_location, "bin", "obj", "%s.%s.%s" % (host_os, arch, build_type), "tests"))
@@ -1804,6 +1829,16 @@ def print_summary(tests):
test_output = test_output.replace("\\n", "\n")
print(test_output)
+ test_output = test_output.replace("/r", "\r")
+ test_output = test_output.replace("/n", "\n")
+ unicode_output = None
+ if sys.version_info < (3,0):
+ # Handle unicode characters in output in python2.*
+ unicode_output = unicode(test_output, "utf-8")
+ else:
+ unicode_output = test_output
+
+ print(unicode_output)
print("")
print("")
@@ -1898,31 +1933,33 @@ def do_setup(host_os,
if gc_stress_c:
setup_coredis_tools(coreclr_repo_location, host_os, arch, core_root)
+ build_info = None
+ is_same_os = None
+ is_same_arch = None
+ is_same_build_type = None
+
+ # We will write out build information into the test directory. This is used
+ # by runtest.py to determine whether we need to rebuild the test wrappers.
+ if os.path.isfile(os.path.join(test_location, "build_info.json")):
+ with open(os.path.join(test_location, "build_info.json")) as file_handle:
+ build_info = json.load(file_handle)
+ is_same_os = build_info["build_os"] == host_os
+ is_same_arch = build_info["build_arch"] == arch
+ is_same_build_type = build_info["build_type"] == build_type
+
# Copy all the native libs to core_root
- if host_os != "Windows_NT":
+ if host_os != "Windows_NT" and not (is_same_os and is_same_arch and is_same_build_type):
copy_native_test_bin_to_core_root(host_os, os.path.join(test_native_bin_location, "src"), core_root)
- correct_line_endings(host_os, test_location)
+ # Line ending only need to be corrected if this is a cross build.
+ correct_line_endings(host_os, test_location)
if unprocessed_args.build_test_wrappers:
build_test_wrappers(host_os, arch, build_type, coreclr_repo_location, test_location)
- else:
- # We will write out build information into the test directory. This is used
- # by runtest.py to determine whether we need to rebuild the test wrappers.
- if os.path.isfile(os.path.join(test_location, "build_info.json")):
- build_info = None
- with open(os.path.join(test_location, "build_info.json")) as file_handle:
- build_info = json.load(file_handle)
-
- is_same_os = build_info["build_os"] == host_os
- is_same_arch = build_info["build_arch"] == arch
- is_same_build_type = build_info["build_type"] == build_type
-
- # We will force a build of the test wrappers if they were cross built
- if not (is_same_os and is_same_arch and is_same_build_type):
- build_test_wrappers(host_os, arch, build_type, coreclr_repo_location, test_location)
- else:
- build_test_wrappers(host_os, arch, build_type, coreclr_repo_location, test_location)
+ elif build_info is None:
+ build_test_wrappers(host_os, arch, build_type, coreclr_repo_location, test_location)
+ elif not (is_same_os and is_same_arch and is_same_build_type):
+ build_test_wrappers(host_os, arch, build_type, coreclr_repo_location, test_location)
return run_tests(host_os,
arch,
@@ -1950,6 +1987,8 @@ def main(args):
host_os, arch, build_type, coreclr_repo_location, product_location, core_root, test_location, test_native_bin_location = setup_args(args)
+ ret_code = 0
+
env = get_environment(test_env=args.test_env)
if not args.analyze_results_only:
if args.test_env is not None:
diff --git a/tests/runtest.sh b/tests/runtest.sh
index 0917094710..e8bd197251 100755
--- a/tests/runtest.sh
+++ b/tests/runtest.sh
@@ -223,6 +223,7 @@ buildXUnitWrappers=
printLastResultsOnly=
generateLayoutOnly=
generateLayout=
+runSequential=
for i in "$@"
do
@@ -340,7 +341,7 @@ do
export testHostDir=${i#*=}
;;
--sequential)
- ((maxProcesses = 1))
+ runSequential=1
;;
--useServerGC)
((serverGC = 1))
@@ -535,7 +536,7 @@ if [ ! -z "$generateLayout" ]; then
runtestPyArguments+=("--generate_layout")
fi
-if [ ! -z "$sequential" ]; then
+if [ ! "$runSequential" -eq 0 ]; then
echo "Run tests sequentially."
runtestPyArguments+=("--sequential")
fi
@@ -552,7 +553,14 @@ if (($doCrossgen!=0)); then
runtestPyArguments+=("--precompile_core_root")
fi
+
+# Default to python3 if it is installed
+__Python=python
+ if command -v python3 &>/dev/null; then
+ __Python=python3
+fi
+
# Run the tests using cross platform runtest.py
echo "python ${scriptPath}/runtest.py ${runtestPyArguments[@]}"
-python "${scriptPath}/runtest.py" "${runtestPyArguments[@]}"
+$__Python "${scriptPath}/runtest.py" "${runtestPyArguments[@]}"
exit "$?"
diff --git a/tests/src/Common/Platform/platformdefines.cpp b/tests/src/Common/Platform/platformdefines.cpp
index 82061ac90d..826e741e06 100644
--- a/tests/src/Common/Platform/platformdefines.cpp
+++ b/tests/src/Common/Platform/platformdefines.cpp
@@ -5,312 +5,312 @@
#include "platformdefines.h"
-LPWSTR HackyConvertToWSTR(char* pszInput)
+LPWSTR HackyConvertToWSTR(const char* pszInput)
{
- size_t cchInput;
- LPWSTR pwszOutput;
- char* pStr;
+ size_t cchInput;
+ LPWSTR pwszOutput;
+ char* pStr;
- if (NULL == pszInput) return NULL;
+ if (NULL == pszInput) return NULL;
- // poor mans strlen
- pStr = pszInput;
- cchInput = 0;
- while('\0' != *pStr) {cchInput++; pStr++;}
- pwszOutput = new WCHAR[ cchInput + 1];
+ // poor mans strlen
+ pStr = (char*)pszInput;
+ cchInput = 0;
+ while('\0' != *pStr) {cchInput++; pStr++;}
+ pwszOutput = new WCHAR[ cchInput + 1];
- for(size_t i=0; i<=cchInput; i++)
- {
- pwszOutput[i] = (WCHAR)pszInput[i];
- }
+ for(size_t i=0; i<=cchInput; i++)
+ {
+ pwszOutput[i] = (WCHAR)pszInput[i];
+ }
- return pwszOutput;
+ return pwszOutput;
}
LPSTR HackyConvertToSTR(LPWSTR pwszInput)
{
- size_t cchInput;
- LPSTR pszOutput;
+ size_t cchInput;
+ LPSTR pszOutput;
- if (NULL == pwszInput) return NULL;
+ if (NULL == pwszInput) return NULL;
- cchInput = wcslen(pwszInput);
- pszOutput = new char[ cchInput + 1];
+ cchInput = wcslen(pwszInput);
+ pszOutput = new char[ cchInput + 1];
- for(size_t i=0; i<=cchInput; i++)
- {
- // ugly down cast
- pszOutput[i] = (char)pwszInput[i];
- }
+ for(size_t i=0; i<=cchInput; i++)
+ {
+ // ugly down cast
+ pszOutput[i] = (char)pwszInput[i];
+ }
- return pszOutput;
+ return pszOutput;
}
error_t TP_scpy_s(LPWSTR strDestination, size_t sizeInWords, LPCWSTR strSource)
{
- size_t cnt;
- // copy sizeInBytes bytes of strSource into strDestination
+ size_t cnt;
+ // copy sizeInBytes bytes of strSource into strDestination
- if (NULL == strDestination || NULL == strSource) return 1;
+ if (NULL == strDestination || NULL == strSource) return 1;
- cnt = 0;
- while(cnt < sizeInWords && '\0' != strSource[cnt])
- {
- strDestination[cnt] = strSource[cnt];
- cnt++;
- }
- strDestination[cnt] = '\0';
+ cnt = 0;
+ while(cnt < sizeInWords && '\0' != strSource[cnt])
+ {
+ strDestination[cnt] = strSource[cnt];
+ cnt++;
+ }
+ strDestination[cnt] = '\0';
- return 0;
+ return 0;
}
error_t TP_scat_s(LPWSTR strDestination, size_t sizeInWords, LPCWSTR strSource)
{
- LPWSTR strEnd;
- // locate the end (ie. '\0') and TP_scpy_s the string
+ LPWSTR strEnd;
+ // locate the end (ie. '\0') and TP_scpy_s the string
- if (NULL == strDestination || NULL == strSource) return 1;
+ if (NULL == strDestination || NULL == strSource) return 1;
- strEnd = strDestination;
- while('\0' != *strEnd) strEnd++;
+ strEnd = strDestination;
+ while('\0' != *strEnd) strEnd++;
- return TP_scpy_s(strEnd, sizeInWords - ((strEnd - strDestination) / sizeof(WCHAR)), strSource);
+ return TP_scpy_s(strEnd, sizeInWords - ((strEnd - strDestination) / sizeof(WCHAR)), strSource);
}
int TP_slen(LPWSTR str)
{
- int len;
+ int len;
- if (NULL == str) return 0;
+ if (NULL == str) return 0;
- len = 0;
- while('\0' != *(str+len)) len++;
+ len = 0;
+ while('\0' != *(str+len)) len++;
- return len;
+ return len;
}
int TP_scmp_s(LPCSTR str1, LPCSTR str2)
{
- // < 0 str1 less than str2
- // 0 str1 identical to str2
- // > 0 str1 greater than str2
+ // < 0 str1 less than str2
+ // 0 str1 identical to str2
+ // > 0 str1 greater than str2
- if (NULL == str1 && NULL != str2) return -1;
- if (NULL != str1 && NULL == str2) return 1;
- if (NULL == str1 && NULL == str2) return 0;
+ if (NULL == str1 && NULL != str2) return -1;
+ if (NULL != str1 && NULL == str2) return 1;
+ if (NULL == str1 && NULL == str2) return 0;
- while (*str1 == *str2 && '\0' != *str1 && '\0' != *str2)
- {
- str1++;
- str2++;
- }
+ while (*str1 == *str2 && '\0' != *str1 && '\0' != *str2)
+ {
+ str1++;
+ str2++;
+ }
- if ('\0' == *str1 && '\0' == *str2) return 0;
+ if ('\0' == *str1 && '\0' == *str2) return 0;
- if ('\0' != *str1) return -1;
- if ('\0' != *str2) return 1;
+ if ('\0' != *str1) return -1;
+ if ('\0' != *str2) return 1;
- return (*str1 > *str2) ? 1 : -1;
+ return (*str1 > *str2) ? 1 : -1;
}
int TP_wcmp_s(LPWSTR str1, LPWSTR str2)
{
- // < 0 str1 less than str2
- // 0 str1 identical to str2
- // > 0 str1 greater than str2
+ // < 0 str1 less than str2
+ // 0 str1 identical to str2
+ // > 0 str1 greater than str2
- if (NULL == str1 && NULL != str2) return -1;
- if (NULL != str1 && NULL == str2) return 1;
- if (NULL == str1 && NULL == str2) return 0;
+ if (NULL == str1 && NULL != str2) return -1;
+ if (NULL != str1 && NULL == str2) return 1;
+ if (NULL == str1 && NULL == str2) return 0;
- while (*str1 == *str2 && '\0' != *str1 && '\0' != *str2)
- {
- str1++;
- str2++;
- }
+ while (*str1 == *str2 && '\0' != *str1 && '\0' != *str2)
+ {
+ str1++;
+ str2++;
+ }
- if ('\0' == *str1 && '\0' == *str2) return 0;
+ if ('\0' == *str1 && '\0' == *str2) return 0;
- if ('\0' != *str1) return -1;
- if ('\0' != *str2) return 1;
+ if ('\0' != *str1) return -1;
+ if ('\0' != *str2) return 1;
- return (*str1 > *str2) ? 1 : -1;
+ return (*str1 > *str2) ? 1 : -1;
}
error_t TP_getenv_s(size_t* pReturnValue, LPWSTR buffer, size_t sizeInWords, LPCWSTR varname)
{
- if (NULL == pReturnValue || NULL == varname) return 1;
+ if (NULL == pReturnValue || NULL == varname) return 1;
#ifdef WINDOWS
-
- size_t returnValue;
+
+ size_t returnValue;
WCHAR buf[100];
if( 0 != _wgetenv_s(&returnValue, buf, 100, varname) || returnValue<=0 )
- return 2;
-
-
- TP_scpy_s(buffer, sizeInWords, (LPWSTR)buf);
+ return 2;
+
+
+ TP_scpy_s(buffer, sizeInWords, (LPWSTR)buf);
#else
- LPSTR pRet;
- pRet = getenv( HackyConvertToSTR((LPWSTR)varname) );
- if (NULL == pRet) return 2;
- TP_scpy_s(buffer, sizeInWords, HackyConvertToWSTR(pRet));
+ LPSTR pRet;
+ pRet = getenv( HackyConvertToSTR((LPWSTR)varname) );
+ if (NULL == pRet) return 2;
+ TP_scpy_s(buffer, sizeInWords, HackyConvertToWSTR(pRet));
#endif
- return 0;
+ return 0;
}
error_t TP_putenv_s(LPTSTR name, LPTSTR value)
{
- if (NULL == name || NULL == value) return 1;
+ if (NULL == name || NULL == value) return 1;
#ifdef WINDOWS
- if( 0 != _putenv_s(name, value))
- return 2;
- else
- return 0;
+ if( 0 != _putenv_s(name, value))
+ return 2;
+ else
+ return 0;
#else
- int retVal = 0;
- char *assignment = (char*) malloc(sizeof(char) * (strlen(name) + strlen(value) + 1));
- sprintf(assignment, "%s=%s", name, value);
-
- if (0 != putenv(assignment))
- retVal = 2;
- free(assignment);
- return retVal;
+ int retVal = 0;
+ char *assignment = (char*) malloc(sizeof(char) * (strlen(name) + strlen(value) + 1));
+ sprintf(assignment, "%s=%s", name, value);
+
+ if (0 != putenv(assignment))
+ retVal = 2;
+ free(assignment);
+ return retVal;
#endif
}
void TP_ZeroMemory(LPVOID buffer, size_t sizeInBytes)
{
- BYTE* bBuf;
+ BYTE* bBuf;
- // clear out the memory with 0's
- if (NULL == buffer) return;
+ // clear out the memory with 0's
+ if (NULL == buffer) return;
- bBuf = (BYTE*)buffer;
- for(size_t i=0; i<sizeInBytes; i++)
- {
- bBuf[i] = 0;
- }
+ bBuf = (BYTE*)buffer;
+ for(size_t i=0; i<sizeInBytes; i++)
+ {
+ bBuf[i] = 0;
+ }
}
error_t TP_itow_s(int num, LPWSTR buffer, size_t sizeInCharacters, int radix)
{
- size_t len;
- int tmpNum;
-
- // only support radix == 10 and only positive numbers
- if (10 != radix) return 1;
- if (0 > num) return 2;
- if (NULL == buffer) return 3;
- if (2 > sizeInCharacters) return 4;
-
- // take care of the trivial case
- if (0 == num)
- {
- buffer[0] = '\0';
- buffer[1] = '\0';
- }
-
- // get length of final string (dumb implementation)
- len = 0;
- tmpNum = num;
- while (0 < tmpNum)
- {
- tmpNum /= 10;
- len++;
- }
-
- if (len >= sizeInCharacters) return 5;
-
- // convert num into a string (backwards)
- buffer[len] = '\0';
- while(0 < num && 0 < len)
- {
+ size_t len;
+ int tmpNum;
+
+ // only support radix == 10 and only positive numbers
+ if (10 != radix) return 1;
+ if (0 > num) return 2;
+ if (NULL == buffer) return 3;
+ if (2 > sizeInCharacters) return 4;
+
+ // take care of the trivial case
+ if (0 == num)
+ {
+ buffer[0] = '\0';
+ buffer[1] = '\0';
+ }
+
+ // get length of final string (dumb implementation)
+ len = 0;
+ tmpNum = num;
+ while (0 < tmpNum)
+ {
+ tmpNum /= 10;
+ len++;
+ }
+
+ if (len >= sizeInCharacters) return 5;
+
+ // convert num into a string (backwards)
+ buffer[len] = '\0';
+ while(0 < num && 0 < len)
+ {
len--;
- buffer[len] = (WCHAR)((num % 10) + '0');
- num /= 10;
- }
+ buffer[len] = (WCHAR)((num % 10) + '0');
+ num /= 10;
+ }
- return 0;
+ return 0;
}
LPWSTR TP_sstr(LPWSTR str, LPWSTR searchStr)
{
- LPWSTR start;
- LPWSTR current;
- LPWSTR searchCurrent;
-
- if (NULL == str || NULL == searchStr) return NULL;
-
- // return a pointer to where searchStr
- // exists in str
- current = str;
- start = NULL;
- searchCurrent = searchStr;
- while('\0' != *current)
- {
- if (NULL != start && '\0' == *searchCurrent)
- {
- break;
- }
-
- if (*current == *searchCurrent)
- {
- searchCurrent++;
- if (NULL == start) start = current;
- }
- else
- {
- searchCurrent = searchStr;
- start = NULL;
- }
- current++;
- }
-
- return start;
+ LPWSTR start;
+ LPWSTR current;
+ LPWSTR searchCurrent;
+
+ if (NULL == str || NULL == searchStr) return NULL;
+
+ // return a pointer to where searchStr
+ // exists in str
+ current = str;
+ start = NULL;
+ searchCurrent = searchStr;
+ while('\0' != *current)
+ {
+ if (NULL != start && '\0' == *searchCurrent)
+ {
+ break;
+ }
+
+ if (*current == *searchCurrent)
+ {
+ searchCurrent++;
+ if (NULL == start) start = current;
+ }
+ else
+ {
+ searchCurrent = searchStr;
+ start = NULL;
+ }
+ current++;
+ }
+
+ return start;
}
DWORD TP_GetFullPathName(LPWSTR fileName, DWORD nBufferLength, LPWSTR lpBuffer)
{
#ifdef WINDOWS
- return GetFullPathNameW(fileName, nBufferLength, lpBuffer, NULL);
+ return GetFullPathNameW(fileName, nBufferLength, lpBuffer, NULL);
#else
- char nativeFullPath[MAX_PATH];
- (void)realpath(HackyConvertToSTR(fileName), nativeFullPath);
- LPWSTR fullPathForCLR = HackyConvertToWSTR(nativeFullPath);
- wcscpy_s(lpBuffer, MAX_PATH, fullPathForCLR);
- return wcslen(lpBuffer);
+ char nativeFullPath[MAX_PATH];
+ (void)realpath(HackyConvertToSTR(fileName), nativeFullPath);
+ LPWSTR fullPathForCLR = HackyConvertToWSTR(nativeFullPath);
+ wcscpy_s(lpBuffer, MAX_PATH, fullPathForCLR);
+ return wcslen(lpBuffer);
#endif
}
DWORD TP_CreateThread(THREAD_ID* tThread, LPTHREAD_START_ROUTINE worker, LPVOID lpParameter)
{
#ifdef WINDOWS
- DWORD ret;
- *tThread = CreateThread(
- NULL,
- 0,
- worker,
- lpParameter,
- 0,
- &ret);
- return ret;
+ DWORD ret;
+ *tThread = CreateThread(
+ NULL,
+ 0,
+ worker,
+ lpParameter,
+ 0,
+ &ret);
+ return ret;
#else
- pthread_create(
- tThread,
- NULL,
- (MacWorker)worker,
- lpParameter);
+ pthread_create(
+ tThread,
+ NULL,
+ (MacWorker)worker,
+ lpParameter);
#ifdef MAC64
- // This is a major kludge...64 bit posix threads just can't be cast into a DWORD and there just isn't
- // a great way to get what we're using for the ID. The fact that we're casting this at all is kind of
- // silly since we're returing the actual thread handle and everything being done to manipulate the thread
- // is done with that. Anyhow, the only thing done with the dword returned from this method is a printf
- // which is good since this DWORD really shouldn't be reliably used. Just in case it is though, return
- // a value that can be traced back to here.
- return 42;
+ // This is a major kludge...64 bit posix threads just can't be cast into a DWORD and there just isn't
+ // a great way to get what we're using for the ID. The fact that we're casting this at all is kind of
+ // silly since we're returing the actual thread handle and everything being done to manipulate the thread
+ // is done with that. Anyhow, the only thing done with the dword returned from this method is a printf
+ // which is good since this DWORD really shouldn't be reliably used. Just in case it is though, return
+ // a value that can be traced back to here.
+ return 42;
#else
- return (DWORD)*tThread;
+ return (DWORD)*tThread;
#endif
#endif
}
@@ -318,8 +318,184 @@ DWORD TP_CreateThread(THREAD_ID* tThread, LPTHREAD_START_ROUTINE worker, LPVOID
void TP_JoinThread(THREAD_ID tThread)
{
#ifdef WINDOWS
- WaitForSingleObject(tThread, INFINITE);
+ WaitForSingleObject(tThread, INFINITE);
#else
- pthread_join(tThread, NULL);
+ pthread_join(tThread, NULL);
#endif
}
+
+#define INTSAFE_E_ARITHMETIC_OVERFLOW ((HRESULT)0x80070216L) // 0x216 = 534 = ERROR_ARITHMETIC_OVERFLOW
+#define ULONG_ERROR (0xffffffffUL)
+#define WIN32_ALLOC_ALIGN (16 - 1)
+//
+// ULONGLONG -> ULONG conversion
+//
+HRESULT ULongLongToULong(ULONGLONG ullOperand, ULONG* pulResult)
+{
+ HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
+ *pulResult = ULONG_ERROR;
+
+ if (ullOperand <= ULONG_MAX)
+ {
+ *pulResult = (ULONG)ullOperand;
+ hr = S_OK;
+ }
+
+ return hr;
+}
+
+HRESULT ULongAdd(ULONG ulAugend, ULONG ulAddend,ULONG* pulResult)
+{
+ HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
+ *pulResult = ULONG_ERROR;
+
+ if ((ulAugend + ulAddend) >= ulAugend)
+ {
+ *pulResult = (ulAugend + ulAddend);
+ hr = S_OK;
+ }
+
+ return hr;
+}
+
+HRESULT ULongMult(ULONG ulMultiplicand, ULONG ulMultiplier, ULONG* pulResult)
+{
+ ULONGLONG ull64Result = UInt32x32To64(ulMultiplicand, ulMultiplier);
+
+ return ULongLongToULong(ull64Result, pulResult);
+}
+
+HRESULT CbSysStringSize(ULONG cchSize, BOOL isByteLen, ULONG *result)
+{
+ if (result == NULL)
+ return E_INVALIDARG;
+
+ // +2 for the null terminator
+ // + DWORD_PTR to store the byte length of the string
+ int constant = sizeof(WCHAR) + sizeof(DWORD_PTR) + WIN32_ALLOC_ALIGN;
+
+ if (isByteLen)
+ {
+ if (SUCCEEDED(ULongAdd(constant, cchSize, result)))
+ {
+ *result = *result & ~WIN32_ALLOC_ALIGN;
+ return S_OK;
+ }
+ }
+ else
+ {
+ ULONG temp = 0; // should not use in-place addition in ULongAdd
+ if (SUCCEEDED(ULongMult(cchSize, sizeof(WCHAR), &temp)) &
+ SUCCEEDED(ULongAdd(temp, constant, result)))
+ {
+ *result = *result & ~WIN32_ALLOC_ALIGN;
+ return S_OK;
+ }
+ }
+ return INTSAFE_E_ARITHMETIC_OVERFLOW;
+}
+
+BSTR TP_SysAllocString(LPWSTR psz)
+{
+#ifdef WINDOWS
+ return SysAllocString(psz);
+#else
+ if(psz == NULL)
+ return NULL;
+ return TP_SysAllocStringLen(psz, (DWORD)wcslen(psz));
+#endif
+}
+
+BSTR TP_SysAllocStringLen(LPWSTR psz, size_t len)
+{
+ ULONG cbTotal = 0;
+
+ if (FAILED(CbSysStringSize((ULONG)len, FALSE, &cbTotal)))
+ return NULL;
+
+ BSTR bstr = (BSTR)TP_CoTaskMemAlloc(cbTotal);
+
+ if(bstr != NULL){
+
+#if defined(_WIN64)
+ // NOTE: There are some apps which peek back 4 bytes to look at the size of the BSTR. So, in case of 64-bit code,
+ // we need to ensure that the BSTR length can be found by looking one DWORD before the BSTR pointer.
+ *(DWORD_PTR *)bstr = (DWORD_PTR) 0;
+ bstr = (BSTR) ((char *) bstr + sizeof (DWORD));
+#endif
+ *(DWORD *)bstr = (DWORD)len * sizeof(OLECHAR);
+
+ bstr = (BSTR) ((char*) bstr + sizeof(DWORD));
+
+ if(psz != NULL){
+ memcpy(bstr, psz, len * sizeof(OLECHAR));
+ }
+
+ bstr[len] = '\0'; // always 0 terminate
+ }
+
+ return bstr;
+}
+
+BSTR TP_SysAllocStringByteLen(LPCSTR psz, size_t len)
+{
+#ifdef WINDOWS
+ return SysAllocStringByteLen(psz, (UINT)len);
+#else
+ BSTR bstr;
+ ULONG cbTotal = 0;
+
+ if (FAILED(CbSysStringSize(len, TRUE, &cbTotal)))
+ return NULL;
+
+ bstr = (BSTR)TP_CoTaskMemAlloc(cbTotal);
+
+ if (bstr != NULL) {
+#if defined(_WIN64)
+ *(DWORD *)((char *)bstr + sizeof (DWORD)) = (DWORD)len;
+#else
+ *(DWORD *)bstr = (DWORD)len;
+#endif
+
+ bstr = (WCHAR*) ((char*) bstr + sizeof(DWORD_PTR));
+
+ if (psz != NULL) {
+ memcpy(bstr, psz, len);
+ }
+
+ // NULL-terminate with both a narrow and wide zero.
+ *((char *)bstr + len) = '\0';
+ *(WCHAR *)((char *)bstr + ((len + 1) & ~1)) = 0;
+ }
+
+ return bstr;
+#endif
+}
+
+void TP_SysFreeString(BSTR bstr)
+{
+#ifdef WINDOWS
+ return SysFreeString(bstr);
+#else
+ if (bstr == NULL)
+ return;
+ TP_CoTaskMemFree((BYTE *)bstr - sizeof(DWORD_PTR));
+#endif
+}
+
+size_t TP_SysStringByteLen(BSTR bstr)
+{
+#ifdef WINDOWS
+ return SysStringByteLen(bstr);
+#else
+ if(bstr == NULL)
+ return 0;
+ int32_t * p32 = (int32_t *) bstr;
+ int32_t * p32_1 = p32 -1;
+ DWORD * d32 = (DWORD *) bstr;
+ DWORD * d32_1 = d32 - 1;
+ //std::cout << p32 << p32_1 << endl;
+ //std::cout << d32 << d32_1 << endl;
+ return (unsigned int)(((DWORD *)bstr)[-1]);
+#endif
+}
diff --git a/tests/src/Common/Platform/platformdefines.h b/tests/src/Common/Platform/platformdefines.h
index 0961e86b2d..aa96483124 100644
--- a/tests/src/Common/Platform/platformdefines.h
+++ b/tests/src/Common/Platform/platformdefines.h
@@ -6,6 +6,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <cstdint>
#ifndef _PLATFORMDEFINES__H
#define _PLATFORMDEFINES__H
@@ -19,7 +20,7 @@
#define FS_SEPERATOR L"\\"
#define PATH_DELIMITER L";"
#define L(t) L##t
-
+#define W(str) L##str
typedef unsigned error_t;
typedef HANDLE THREAD_ID;
@@ -30,11 +31,34 @@ typedef HANDLE THREAD_ID;
#include <pthread.h>
typedef char16_t WCHAR;
-typedef unsigned long DWORD;
+typedef unsigned int DWORD;
typedef int BOOL;
typedef WCHAR *LPWSTR, *PWSTR;
typedef const WCHAR *LPCWSTR, *PCWSTR;
+typedef long HRESULT;
+#define LONGLONG long long
+#define ULONGLONG unsigned LONGLONG
+typedef unsigned long ULONG, *PULONG;
+#define S_OK 0x0
+#define SUCCEEDED(_hr) ((HRESULT)(_hr) >= 0)
+#define FAILED(_hr) ((HRESULT)(_hr) < 0)
+
+#ifdef ULONG_MAX
+#undef ULONG_MAX
+#endif
+#define ULONG_MAX 0xffffffffUL
+#define CCH_BSTRMAX 0x7FFFFFFF // 4 + (0x7ffffffb + 1 ) * 2 ==> 0xFFFFFFFC
+#define CB_BSTRMAX 0xFFFFFFFa // 4 + (0xfffffff6 + 2) ==> 0xFFFFFFFC
+
+#ifdef RC_INVOKED
+#define _HRESULT_TYPEDEF_(_sc) _sc
+#else // RC_INVOKED
+#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc)
+#endif // RC_INVOKED
+#define E_INVALIDARG _HRESULT_TYPEDEF_(0x80070057L)
+#define UInt32x32To64(a, b) ((unsigned __int64)((ULONG)(a)) * (unsigned __int64)((ULONG)(b)))
+
#ifndef TRUE
#define TRUE 1
#endif
@@ -51,9 +75,11 @@ typedef const WCHAR *LPCWSTR, *PCWSTR;
#if __i386__
#define __stdcall __attribute__((stdcall))
#define _cdecl __attribute__((cdecl))
+#define __cdecl __attribute__((cdecl))
#else
#define __stdcall
#define _cdecl
+#define __cdecl
#endif
#endif
@@ -63,11 +89,12 @@ typedef const WCHAR *LPCWSTR, *PCWSTR;
#define DLL_EXPORT
#endif
-LPWSTR HackyConvertToWSTR(char* pszInput);
+LPWSTR HackyConvertToWSTR(const char* pszInput);
#define FS_SEPERATOR L("/")
#define PATH_DELIMITER L(":")
#define L(t) HackyConvertToWSTR(t)
+#define W(str) u##str
#define MAX_PATH 260
typedef pthread_t THREAD_ID;
@@ -91,6 +118,8 @@ typedef unsigned char BYTE;
typedef WCHAR OLECHAR;
#endif
+typedef ULONG_PTR DWORD_PTR;
+
//
// Method declarations
//
@@ -110,6 +139,13 @@ void TP_JoinThread(THREAD_ID tThread);
void TP_DebugBreak();
DWORD TP_GetFullPathName(LPWSTR fileName, DWORD nBufferLength, LPWSTR lpBuffer);
+typedef WCHAR* BSTR;
+BSTR TP_SysAllocStringByteLen(LPSTR psz, size_t len);
+void TP_SysFreeString(BSTR bstr);
+size_t TP_SysStringByteLen(BSTR bstr);
+BSTR TP_SysAllocStringLen(LPWSTR psz, size_t len);
+BSTR TP_SysAllocString(LPWSTR psz);
+
//
// Method redirects
//
diff --git a/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp b/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp
index 83c844e412..9e6be4ff13 100644
--- a/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp
+++ b/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp
@@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
#include <xplatform.h>
-
+#include "platformdefines.h"
const int ARRAY_SIZE = 100;
template<typename T> bool IsObjectEquals(T o1, T o2);
diff --git a/tests/src/Interop/CMakeLists.txt b/tests/src/Interop/CMakeLists.txt
index fad9760d99..7b509d6174 100644
--- a/tests/src/Interop/CMakeLists.txt
+++ b/tests/src/Interop/CMakeLists.txt
@@ -2,6 +2,7 @@ if(WIN32)
list(APPEND LINK_LIBRARIES_ADDITIONAL
ole32.lib
advapi32.lib
+ OleAut32.lib
)
endif(WIN32)
@@ -26,6 +27,7 @@ add_subdirectory(RefCharArray)
add_subdirectory(StringMarshalling/LPSTR)
add_subdirectory(StringMarshalling/LPTSTR)
add_subdirectory(StringMarshalling/UTF8)
+add_subdirectory(StringMarshalling/BSTR)
add_subdirectory(MarshalAPI/FunctionPointer)
add_subdirectory(MarshalAPI/IUnknown)
add_subdirectory(SizeConst)
diff --git a/tests/src/Interop/StringMarshalling/BSTR/BSTRTest.cs b/tests/src/Interop/StringMarshalling/BSTR/BSTRTest.cs
new file mode 100644
index 0000000000..fbd0b729d4
--- /dev/null
+++ b/tests/src/Interop/StringMarshalling/BSTR/BSTRTest.cs
@@ -0,0 +1,200 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+using System;
+using System.Reflection;
+using System.Text;
+using NativeDefs;
+
+class Test
+{
+
+ #region "Report Failure"
+ static int fails = 0; //record the fail numbers
+ // Overload methods for reportfailure
+ static int ReportFailure(string s)
+ {
+ Console.WriteLine(" === Fail:" + s);
+ return (++fails);
+ }
+ static int ReportFailure(string expect, string actual)
+ {
+ Console.WriteLine(" === Fail: Expected:" + expect + "\n Actual:" + actual);
+ return (++fails);
+ }
+ static int ReportFailure(string describe, string expect, string actual)
+ {
+ Console.WriteLine(" === Fail: " + describe + "\n\tExpected:" + expect + "\n\tActual:" + actual);
+ return (++fails);
+ }
+ #endregion
+
+ #region "Helper"
+ // ************************************************************
+ // Returns the appropriate exit code
+ // *************************************************************
+ static int ExitTest()
+ {
+ if (fails == 0)
+ {
+ Console.WriteLine("PASS");
+ return 100;
+ }
+ else
+ {
+ Console.WriteLine("FAIL - " + fails + " failure(s) occurred");
+ return 101;
+ }
+ }
+ #endregion
+
+ #region ReversePInvoke
+
+ public static string Call_DelMarshal_InOut(string s)
+ {
+ string strRet;
+ if (!s.Equals("\u0148"))
+ {
+ Console.WriteLine(s.Length);
+ ReportFailure("Method Call_DelMarshal_InOut[Managed Side],The passed string is wrong", "\u0148", s);
+ strRet = "\0\0\0";
+ return strRet;
+ }
+ s = "Managed";
+ strRet = "Return\0Return\0";
+ return strRet;
+ }
+
+ public static string Call_DelMarshalPointer_Out(out string s)
+ {
+ s = "Native\0String\0";
+ string strRet = "Return\0Return\0";
+ return strRet;
+ }
+
+ public static StringBuilder Call_Del_MarshalStrB_InOut(StringBuilder r)
+ {
+ StringBuilder retstr = new StringBuilder("Return\0Native");
+
+ if (!r.ToString().Equals(new StringBuilder("a", 1).ToString()))
+ {
+ ReportFailure("Method Call_Del_MarshalStrB_InOut[Managed Side] Failure. String is different than expected", "ă", r.ToString());
+ }
+ r.Replace('a', 'm');
+ return retstr;
+ }
+
+ public static StringBuilder Call_Del_MarshalStrB_Out(out StringBuilder r)
+ {
+ StringBuilder retstr = new StringBuilder("Native\0Native");
+ r = new StringBuilder("Managed", 7);
+ return retstr;
+ }
+
+ #endregion
+
+ public static int Main(string[] args)
+ {
+#pragma warning disable 0219
+ string strManaged = "Managed\0String\0";
+ string strRet = "a";
+ StringBuilder strBRet = new StringBuilder("a", 1);
+ string strNative = " Native";
+ StringBuilder strBNative = new StringBuilder(" Native", 7);
+#pragma warning restore 0219
+
+ //since the out attributes doesnt work for string, so i dont check the out value.
+ string strPara2 = strManaged;
+ string strRet2 = PInvokeDef.Marshal_InOut(strPara2);
+ if (!strRet2.Equals(strRet))
+ {
+ ReportFailure("Method PInvokeDef.Marshal_InOut[Managed Side],The Return string is wrong", strRet, strRet2);
+ }
+ if (!strPara2.Equals(strManaged))
+ {
+ ReportFailure("Method PInvokeDef.Marshal_InOut[Managed Side],The Parameter string is Changed", strManaged, strPara2);
+ }
+
+ //TestMethod3
+ string strPara3 = strManaged;
+ string strRet3 = PInvokeDef.Marshal_Out(strPara3);
+ if (!strRet.Equals(strRet3))
+ {
+ ReportFailure("Method PInvokeDef.Marshal_Out[Managed Side],The Return string is wrong", strRet, strRet3);
+ }
+ if (!strPara3.Equals(strManaged))
+ {
+ ReportFailure("Method PInvokeDef.Marshal_Out[Managed Side],The Parameter string is not Changed", strManaged, strPara3);
+ }
+
+ //TestMethod5
+ string strPara5 = strManaged;
+ string strRet5 = PInvokeDef.MarshalPointer_InOut(ref strPara5);
+
+ if (!strRet5.Equals(strRet))
+ {
+ ReportFailure("Method PInvokeDef.MarshalPointer_InOut[Managed Side],The Return string is wrong", strRet, strRet5);
+ }
+ if (!strPara5.Equals(strNative))
+ {
+ ReportFailure("Method PInvokeDef.MarshalPointer_InOut[Managed Side],The Passed string is wrong", strNative, strPara5);
+ }
+
+ //TestMethod6
+ string strPara6 = strManaged;
+ string strRet6 = PInvokeDef.MarshalPointer_Out(out strPara6);
+ if (!strRet6.Equals(strRet))
+ {
+ ReportFailure("Method PInvokeDef.MarshalPointer_Out[Managed Side],The Return string is wrong", strRet, strRet6);
+ }
+ if (!strPara6.Equals(strNative))
+ {
+ ReportFailure("Method PInvokeDef.MarshalPointer_Out[Managed Side],The Passed string is wrong", strNative, strPara6);
+ }
+
+ #region ReversePinvoke
+ DelMarshal_InOut d1 = new DelMarshal_InOut(Call_DelMarshal_InOut);
+ if (!PInvokeDef.RPinvoke_DelMarshal_InOut(d1, "\u0148"))
+ {
+ ReportFailure("Method RPinvoke_DelMarshal_InOut[Managed Side],Return value is false");
+ }
+
+ DelMarshalPointer_Out d2 = new DelMarshalPointer_Out(Call_DelMarshalPointer_Out);
+ if (!PInvokeDef.RPinvoke_DelMarshalPointer_Out(d2))
+ {
+ ReportFailure("Method RPinvoke_DelMarshal_Out[Managed Side],Return value is false");
+ }
+
+ #endregion
+ #region DelegatePInvoke
+
+ Del_Marshal_InOut d3 = new Del_Marshal_InOut(PInvokeDef.Marshal_InOut);
+ string strPara9 = strManaged;
+ string strRet9 = d3(strPara9);
+ if (!strRet9.Equals(strRet))
+ {
+ ReportFailure("Method Del_Marshal_InOut[Managed Side],The Return string is wrong", strRet, strRet9);
+ }
+ if (!strPara9.Equals(strManaged))
+ {
+ ReportFailure("Method Del_Marshal_InOut[Managed Side],The Parameter string is Changed", strManaged, strPara9);
+ }
+
+ Del_MarshalPointer_Out d4 = new Del_MarshalPointer_Out(PInvokeDef.MarshalPointer_Out);
+ string strPara10 = strManaged;
+ string strRet10 = d4(out strPara10);
+ if (!strRet10.Equals(strRet))
+ {
+ ReportFailure("Method Del_MarshalPointer_Out[Managed Side],The Return string is wrong", strRet, strRet10);
+ }
+ if (!strPara10.Equals(strNative))
+ {
+ ReportFailure("Method Del_MarshalPointer_Out[Managed Side],The Passed string is wrong", strNative, strPara10);
+ }
+
+ #endregion
+ return ExitTest();
+ }
+}
diff --git a/tests/src/Interop/StringMarshalling/BSTR/BSTRTest.csproj b/tests/src/Interop/StringMarshalling/BSTR/BSTRTest.csproj
new file mode 100644
index 0000000000..05c7287f93
--- /dev/null
+++ b/tests/src/Interop/StringMarshalling/BSTR/BSTRTest.csproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>BSTRTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{176EC495-7AE9-42CF-A591-06A382DB4048}</ProjectGuid>
+ <OutputType>exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj">
+ <Project>{c8c0dc74-fac4-45b1-81fe-70c4808366e0}</Project>
+ <Name>CoreCLRTestLibrary</Name>
+ </ProjectReference>
+ <ProjectReference Include="CMakeLists.txt">
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Interop/StringMarshalling/BSTR/BSTRTestNative.cpp b/tests/src/Interop/StringMarshalling/BSTR/BSTRTestNative.cpp
new file mode 100644
index 0000000000..9a4668bf2e
--- /dev/null
+++ b/tests/src/Interop/StringMarshalling/BSTR/BSTRTestNative.cpp
@@ -0,0 +1,164 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include "platformdefines.h"
+
+WCHAR strManaged[] = W("Managed\0String\0");
+size_t lenstrManaged = sizeof(strManaged) - sizeof(WCHAR);
+
+WCHAR strReturn[] = W("a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
+WCHAR strerrReturn[] = W("error");
+
+WCHAR strNative[] = W(" Native");
+size_t lenstrNative = sizeof(strNative) - sizeof(WCHAR);
+
+//Test Method1
+extern "C" BSTR ReturnString()
+{
+ return TP_SysAllocString(strReturn);
+}
+
+extern "C" BSTR ReturnErrorString()
+{
+ return TP_SysAllocString(strerrReturn);
+}
+
+//Test Method2
+extern "C" DLL_EXPORT BSTR Marshal_InOut(/*[In,Out]*/BSTR s)
+{
+ //Check the Input
+ size_t len = TP_SysStringByteLen(s);
+
+ if (len != lenstrManaged || memcmp(s,strManaged,lenstrManaged) != 0)
+ {
+ printf("Error in Function Marshal_InOut(Native Client)\n");
+ printf("Error: Actual: %d, Expected: %d\n",(int32_t) len, (int32_t)lenstrManaged);
+
+ return ReturnErrorString();
+ }
+
+ //In-Place Change
+ memcpy(s, strNative, len);
+
+ //Return
+ return ReturnString();
+}
+
+
+extern "C" DLL_EXPORT BSTR Marshal_Out(/*[Out]*/BSTR s)
+{
+ s = TP_SysAllocString(strNative);
+
+ //Return
+ return ReturnString();
+}
+
+
+extern "C" DLL_EXPORT BSTR MarshalPointer_InOut(/*[in,out]*/BSTR *s)
+{
+ //Check the Input
+ size_t len = TP_SysStringByteLen(*s);
+
+ if (len != lenstrManaged || memcmp(*s,strManaged,lenstrManaged)!=0)
+ {
+ printf("Error in Function MarshalPointer_InOut\n");
+ printf("Error: Expected: %d, Actual: %d", (int32_t)lenstrManaged, (int32_t)len);
+
+ return ReturnErrorString();
+ }
+
+ //Allocate New
+ TP_SysFreeString(*s);
+ *s = TP_SysAllocString(strNative);
+
+ //Return
+ return ReturnString();
+}
+
+extern "C" DLL_EXPORT BSTR MarshalPointer_Out(/*[out]*/ BSTR *s)
+{
+ *s = TP_SysAllocString(strNative);
+ return ReturnString();
+}
+
+typedef BSTR (__stdcall * Test_DelMarshal_InOut)(/*[in]*/ BSTR s);
+extern "C" DLL_EXPORT BOOL __cdecl RPinvoke_DelMarshal_InOut(Test_DelMarshal_InOut d, /*[in]*/ BSTR s)
+{
+ BSTR str = d(s);
+ WCHAR ret[] = W("Return\0Return\0");
+
+ size_t lenstr = TP_SysStringByteLen(str);
+ size_t lenret = sizeof(ret) - sizeof(WCHAR);
+
+ if (lenret != lenstr || memcmp(str,ret,lenstr) != 0)
+ {
+ printf("Error in RPinvoke_DelMarshal_InOut, Returned value didn't match\n");
+ return FALSE;
+ }
+
+ TP_SysFreeString(str);
+ return TRUE;
+}
+
+//
+// PInvokeDef.cs explicitly declares that RPinvoke_DelMarshalPointer_Out uses STDCALL
+//
+typedef BSTR (__cdecl * Test_DelMarshalPointer_Out)(/*[out]*/ BSTR * s);
+extern "C" DLL_EXPORT BOOL __stdcall RPinvoke_DelMarshalPointer_Out(Test_DelMarshalPointer_Out d)
+{
+ BSTR str;
+ BSTR ret = d(&str);
+
+ WCHAR changedstr[] = W("Native\0String\0");
+
+ size_t lenstr = TP_SysStringByteLen(str);
+ size_t lenchangedstr = sizeof(changedstr) - sizeof(WCHAR);
+
+ if ( lenstr != lenchangedstr || (memcmp(str,changedstr,lenstr)!=0))
+ {
+ printf("Error in RPinvoke_DelMarshalPointer_Out, Value didn't change\n");
+ return FALSE;
+ }
+
+ WCHAR expected[] = W("Return\0Return\0");
+ size_t lenret = TP_SysStringByteLen(ret);
+ size_t lenexpected = sizeof(expected) - sizeof(WCHAR);
+
+ if (lenret != lenexpected || memcmp(ret,expected,lenret)!=0)
+ {
+ printf("Error in RPinvoke_DelMarshalPointer_Out, Return vaue is different than expected\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+//
+// PInvokeDef.cs explicitly declares that ReverseP_MarshalStrB_InOut uses STDCALL
+//
+typedef BSTR (__stdcall * Test_Del_MarshalStrB_InOut)(/*[in,out]*/ BSTR s);
+extern "C" DLL_EXPORT BOOL __stdcall ReverseP_MarshalStrB_InOut(Test_Del_MarshalStrB_InOut d, /*[in]*/ BSTR s)
+{
+ BSTR ret = d((BSTR)s);
+ WCHAR expected[] = W("Return");
+ size_t lenret = TP_SysStringByteLen(ret);
+ size_t lenexpected = sizeof(expected) - sizeof(WCHAR);
+
+ if (lenret != lenexpected || memcmp(ret,expected,lenret) != 0)
+ {
+ printf("Error in ReverseP_MarshalStrB_InOut, Return vaue is different than expected\n");
+ return FALSE;
+ }
+
+ WCHAR expectedchange[] = W("m");
+ size_t lenstr = TP_SysStringByteLen(s);
+ size_t lenexpectedchange = sizeof(expectedchange) - sizeof(WCHAR);
+
+ if (lenstr != lenexpectedchange || memcmp(s,expectedchange,lenstr) != 0)
+ {
+ printf("Error in ReverseP_MarshalStrB_InOut, Value didn't get change\n");
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/tests/src/Interop/StringMarshalling/BSTR/CMakeLists.txt b/tests/src/Interop/StringMarshalling/BSTR/CMakeLists.txt
new file mode 100644
index 0000000000..d485437f54
--- /dev/null
+++ b/tests/src/Interop/StringMarshalling/BSTR/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required (VERSION 2.6)
+project (BSTRTestNative)
+include_directories(${INC_PLATFORM_DIR})
+set(SOURCES BSTRTestNative.cpp)
+
+# add the executable
+add_library (BSTRTestNative SHARED ${SOURCES})
+
+if(WIN32)
+ list(APPEND LINK_LIBRARIES_ADDITIONAL
+ OleAut32.lib
+ )
+endif(WIN32)
+
+target_link_libraries(BSTRTestNative ${LINK_LIBRARIES_ADDITIONAL})
+
+# add the install targets
+install (TARGETS BSTRTestNative DESTINATION bin)
diff --git a/tests/src/Interop/StringMarshalling/BSTR/PinvokeDef.cs b/tests/src/Interop/StringMarshalling/BSTR/PinvokeDef.cs
new file mode 100644
index 0000000000..241eeff2e5
--- /dev/null
+++ b/tests/src/Interop/StringMarshalling/BSTR/PinvokeDef.cs
@@ -0,0 +1,53 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+using System;
+using System.Reflection;
+using System.Text;
+
+namespace NativeDefs
+{
+
+ [return: MarshalAs(UnmanagedType.BStr)]
+ public delegate string Del_MarshalPointer_Out([MarshalAs(UnmanagedType.BStr)] out string s);
+
+ [return: MarshalAs(UnmanagedType.BStr)]
+ public delegate string Del_Marshal_InOut([MarshalAs(UnmanagedType.BStr)]string s);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ [return: MarshalAs(UnmanagedType.BStr)]
+ public delegate string DelMarshalPointer_Out([MarshalAs(UnmanagedType.BStr)][Out] out string s);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
+ [return: MarshalAs(UnmanagedType.BStr)]
+ public delegate string DelMarshal_InOut([MarshalAs(UnmanagedType.BStr)][In, Out]string s);
+
+ public static class PInvokeDef
+ {
+ public const string NativeBinaryName = "BSTRTestNative";
+
+ [DllImport(NativeBinaryName)]
+ [return: MarshalAs(UnmanagedType.BStr)]
+ public static extern string Marshal_InOut([In, Out][MarshalAs(UnmanagedType.BStr)]string s);
+
+ [DllImport(NativeBinaryName)]
+ [return: MarshalAs(UnmanagedType.BStr)]
+ public static extern string Marshal_Out([Out][MarshalAs(UnmanagedType.BStr)]string s);
+
+ [DllImport(NativeBinaryName)]
+ [return: MarshalAs(UnmanagedType.BStr)]
+ public static extern string MarshalPointer_InOut([MarshalAs(UnmanagedType.BStr)]ref string s);
+
+ [DllImport(NativeBinaryName)]
+ [return: MarshalAs(UnmanagedType.BStr)]
+ public static extern string MarshalPointer_Out([MarshalAs(UnmanagedType.BStr)]out string s);
+
+ [DllImport(NativeBinaryName, CallingConvention = CallingConvention.Cdecl)]
+ public static extern bool RPinvoke_DelMarshal_InOut(DelMarshal_InOut d, [MarshalAs(UnmanagedType.BStr)]string s);
+
+ [DllImport(NativeBinaryName, CallingConvention = CallingConvention.StdCall)]
+ public static extern bool RPinvoke_DelMarshalPointer_Out(DelMarshalPointer_Out d);
+ }
+}
diff --git a/tests/src/Interop/common/types.h b/tests/src/Interop/common/types.h
index 37c14546ae..1443e5920f 100755
--- a/tests/src/Interop/common/types.h
+++ b/tests/src/Interop/common/types.h
@@ -9,7 +9,6 @@
#define INT_MIN (-2147483647 - 1)
typedef char16_t WCHAR;
-typedef unsigned long DWORD;
typedef int BOOL;
typedef WCHAR *LPWSTR, *PWSTR;
typedef const WCHAR *LPCWSTR, *PCWSTR;
@@ -18,7 +17,6 @@ typedef char* LPSTR;
typedef const char* LPCSTR;
typedef void* FARPROC;
typedef void* HMODULE;
-typedef void* ULONG_PTR;
typedef unsigned error_t;
typedef void* LPVOID;
typedef unsigned char BYTE;
@@ -37,8 +35,6 @@ typedef unsigned short USHORT;
typedef signed short SHORT;
typedef unsigned short WORD, *PWORD, *LPWORD;
-typedef int* DWORD_PTR;
-
#ifndef TRUE
#define TRUE 1
#endif
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_20260/GitHub_20260.cs b/tests/src/JIT/Regression/JitBlue/GitHub_20260/GitHub_20260.cs
new file mode 100644
index 0000000000..2224f6556a
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_20260/GitHub_20260.cs
@@ -0,0 +1,48 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Globalization;
+using System.Numerics;
+
+namespace GitHub_20260
+{
+ class Program
+ {
+ static int Main(string[] args)
+ {
+ // The jit will devirtualize the call to ToString and then undo the box.
+ // Make sure that happens properly for vectors.
+
+ Vector<double> x = new Vector<double>();
+ string s = ((IFormattable)x).ToString("G", CultureInfo.InvariantCulture);
+ string e = null;
+
+ switch (Vector<double>.Count)
+ {
+ case 2:
+ e = "<0, 0>";
+ break;
+ case 4:
+ e = "<0, 0, 0, 0>";
+ break;
+ case 8:
+ e = "<0, 0, 0, 0, 0, 0, 0, 0>";
+ break;
+ default:
+ e = "unexpected vector length";
+ break;
+ }
+
+ if (s != e)
+ {
+ Console.WriteLine($"FAIL: Expected {e}, got {s}");
+ return -1;
+ }
+
+ Console.WriteLine($"PASS: {s}");
+ return 100;
+ }
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_20260/GitHub_20260.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_20260/GitHub_20260.csproj
new file mode 100644
index 0000000000..e191e01217
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_20260/GitHub_20260.csproj
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "></PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildProjectName).cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
diff --git a/tests/src/Regressions/coreclr/16775/sharedinterfacemethod.il b/tests/src/Regressions/coreclr/16775/sharedinterfacemethod.il
new file mode 100644
index 0000000000..308ead9a37
--- /dev/null
+++ b/tests/src/Regressions/coreclr/16775/sharedinterfacemethod.il
@@ -0,0 +1,91 @@
+.assembly extern System.Runtime { }
+
+.assembly sharedinterfacemethod { }
+
+.class interface private abstract auto ansi IFoo`1<T>
+{
+ .method public hidebysig virtual newslot instance class [System.Runtime]System.Type Frob() cil managed
+ {
+ ldtoken !0
+ call class [System.Runtime]System.Type class [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle)
+ ret
+ }
+}
+
+.class private auto ansi beforefieldinit Fooer
+ extends [System.Runtime]System.Object
+ implements class IFoo`1<class [System.Runtime]System.Object>,
+ class IFoo`1<valuetype [System.Runtime]System.Int32>
+{
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ ldarg.0
+ call instance void [System.Runtime]System.Object::.ctor()
+ ret
+ }
+}
+
+.method public hidebysig static int32 Main() cil managed
+{
+ .entrypoint
+
+ // Callvirt to a shared interface method
+
+ newobj instance void Fooer::.ctor()
+ callvirt instance class [System.Runtime]System.Type class IFoo`1<valuetype [System.Runtime]System.Int32>::Frob()
+ ldtoken valuetype [System.Runtime]System.Int32
+ call class [System.Runtime]System.Type class [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle)
+ ceq
+ brtrue UnsharedCallvirtIsGood
+
+ ldc.i4.1
+ ret
+
+UnsharedCallvirtIsGood:
+
+ // Call to a shared interface
+
+ newobj instance void Fooer::.ctor()
+ call instance class [System.Runtime]System.Type class IFoo`1<valuetype [System.Runtime]System.Int32>::Frob()
+ ldtoken valuetype [System.Runtime]System.Int32
+ call class [System.Runtime]System.Type class [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle)
+ ceq
+ brtrue UnsharedCallIsGood
+
+ ldc.i4.2
+ ret
+
+UnsharedCallIsGood:
+
+ // Callvirt to an unshared interface method
+
+ newobj instance void Fooer::.ctor()
+ callvirt instance class [System.Runtime]System.Type class IFoo`1<class [System.Runtime]System.Object>::Frob()
+ ldtoken class [System.Runtime]System.Object
+ call class [System.Runtime]System.Type class [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle)
+ ceq
+ brtrue SharedCallvirtIsGood
+
+ ldc.i4.3
+ ret
+
+SharedCallvirtIsGood:
+
+ // Call to an unshared interface method
+
+ newobj instance void Fooer::.ctor()
+ call instance class [System.Runtime]System.Type class IFoo`1<class [System.Runtime]System.Object>::Frob()
+ ldtoken class [System.Runtime]System.Object
+ call class [System.Runtime]System.Type class [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle)
+ ceq
+ brtrue SharedCallIsGood
+
+ ldc.i4.4
+ ret
+
+SharedCallIsGood:
+
+ ldc.i4 100
+ ret
+}
diff --git a/tests/src/Regressions/coreclr/16775/sharedinterfacemethod.ilproj b/tests/src/Regressions/coreclr/16775/sharedinterfacemethod.ilproj
new file mode 100644
index 0000000000..7521917db5
--- /dev/null
+++ b/tests/src/Regressions/coreclr/16775/sharedinterfacemethod.ilproj
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{85DFC527-4DB1-595E-A7D7-E94EE1F8140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="sharedinterfacemethod.il" />
+ </ItemGroup>
+
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/dir.props b/tests/src/dir.props
index 9c367e208d..b56c686d1d 100644
--- a/tests/src/dir.props
+++ b/tests/src/dir.props
@@ -46,6 +46,7 @@
<OutputPath>$(BaseOutputPathWithConfig)$(BuildProjectRelativeDir)\</OutputPath>
<TestWorkingDir Condition="'$(TestWorkingDir)'==''">$(BaseOutputPath)\testStagingDir\</TestWorkingDir>
<TestPath Condition="'$(TestPath)'==''">$(TestWorkingDir)$(OSPlatformConfig)\$(MSBuildProjectName)/</TestPath>
+ <SkipXunitDependencyCopying>true</SkipXunitDependencyCopying>
</PropertyGroup>
<!-- Disable some standard properties for building our projects -->
diff --git a/tests/src/tracing/tracecontrol/TraceControl.cs b/tests/src/tracing/tracecontrol/TraceControl.cs
new file mode 100644
index 0000000000..fbdc97abf8
--- /dev/null
+++ b/tests/src/tracing/tracecontrol/TraceControl.cs
@@ -0,0 +1,113 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
+using Tracing.Tests.Common;
+
+using Microsoft.Diagnostics.Tracing;
+using Microsoft.Diagnostics.Tracing.Parsers.Clr;
+
+namespace Tracing.Tests
+{
+ public static class TraceControlTest
+ {
+ private static string ConfigFileContents = @"
+OutputPath=.
+CircularMB=2048
+Providers=*:0xFFFFFFFFFFFFFFFF:5
+";
+
+ private const int BytesInOneMB = 1024 * 1024;
+
+ /// <summary>
+ /// This test collects a trace of itself and then performs some basic validation on the trace.
+ /// </summary>
+ public static int Main(string[] args)
+ {
+ // Calculate the path to the config file.
+ string configFileName = Assembly.GetEntryAssembly().GetName().Name + ".eventpipeconfig";
+ string configFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, configFileName);
+ Console.WriteLine("Calculated config file path: " + configFilePath);
+
+ // Write the config file to disk.
+ File.WriteAllText(configFilePath, ConfigFileContents);
+ Console.WriteLine("Wrote contents of config file.");
+
+ // Wait 5 seconds to ensure that tracing has started.
+ Console.WriteLine("Waiting 5 seconds for the config file to be picked up by the next poll operation.");
+ Thread.Sleep(TimeSpan.FromSeconds(5));
+
+ // Do some work that we can look for in the trace.
+ Console.WriteLine("Do some work that will be captured by the trace.");
+ GC.Collect(2, GCCollectionMode.Forced);
+ Console.WriteLine("Done with the work.");
+
+ // Delete the config file to start tracing.
+ File.Delete(configFilePath);
+ Console.WriteLine("Deleted the config file.");
+
+ // Build the full path to the trace file.
+ string[] traceFiles = Directory.GetFiles(".", "*.netperf", SearchOption.TopDirectoryOnly);
+ Assert.Equal("traceFiles.Length == 1", traceFiles.Length, 1);
+ string traceFilePath = traceFiles[0];
+
+ // Poll the file system and wait for the trace file to be written.
+ Console.WriteLine("Wait for the config file deletion to be picked up and for the trace file to be written.");
+
+ // Wait for 1 second, which is the poll time when tracing is enabled.
+ Thread.Sleep(TimeSpan.FromSeconds(1));
+
+ // Poll for file size changes to the trace file itself. When the size of the trace file hasn't changed for 5 seconds, consider it fully written out.
+ Console.WriteLine("Waiting for the trace file to be written. Poll every second to watch for 5 seconds of no file size changes.");
+ long lastSizeInBytes = 0;
+ DateTime timeOfLastChangeUTC = DateTime.UtcNow;
+ do
+ {
+ FileInfo traceFileInfo = new FileInfo(traceFilePath);
+ long currentSizeInBytes = traceFileInfo.Length;
+ Console.WriteLine("Trace file size: " + ((double)currentSizeInBytes / BytesInOneMB));
+
+ if (currentSizeInBytes > lastSizeInBytes)
+ {
+ lastSizeInBytes = currentSizeInBytes;
+ timeOfLastChangeUTC = DateTime.UtcNow;
+ }
+
+ Thread.Sleep(TimeSpan.FromSeconds(1));
+
+ } while (DateTime.UtcNow.Subtract(timeOfLastChangeUTC) < TimeSpan.FromSeconds(5));
+
+ int retVal = 0;
+
+ // Use TraceEvent to consume the trace file and look for the work that we did.
+ Console.WriteLine("Using TraceEvent to parse the file to find the work that was done during trace capture.");
+ using (var trace = TraceEventDispatcher.GetDispatcherFromFileName(traceFilePath))
+ {
+ string gcReasonInduced = GCReason.Induced.ToString();
+ string providerName = "Microsoft-Windows-DotNETRuntime";
+ string gcTriggeredEventName = "GC/Triggered";
+
+ trace.Clr.GCTriggered += delegate (GCTriggeredTraceData data)
+ {
+ if (gcReasonInduced.Equals(data.Reason.ToString()))
+ {
+ Console.WriteLine("Detected an induced GC");
+ retVal = 100;
+ }
+ };
+
+ trace.Process();
+ }
+
+ // Clean-up the resulting trace file.
+ File.Delete(traceFilePath);
+
+ return retVal;
+ }
+ }
+}
diff --git a/tests/src/tracing/tracecontrol/tracecontrol.csproj b/tests/src/tracing/tracecontrol/tracecontrol.csproj
new file mode 100644
index 0000000000..dca25a2e34
--- /dev/null
+++ b/tests/src/tracing/tracecontrol/tracecontrol.csproj
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{8E3244CB-407F-4142-BAAB-E7A55901A5FA}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="TraceControl.cs" />
+ <ProjectReference Include="../common/common.csproj" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>