You've already forked linux-packaging-mono
Imported Upstream version 5.2.0.175
Former-commit-id: bb0468d0f257ff100aa895eb5fe583fb5dfbf900
This commit is contained in:
parent
4bdbaf4a88
commit
966bba02bb
23
external/corert/tests/src/Simple/Add1/Add1.cs
vendored
23
external/corert/tests/src/Simple/Add1/Add1.cs
vendored
@@ -1,23 +0,0 @@
|
||||
// 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.Runtime.CompilerServices;
|
||||
public class BringUpTest
|
||||
{
|
||||
const int Pass = 100;
|
||||
const int Fail = -1;
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.NoInlining)]
|
||||
public static int Add1(int x) { return x+1; }
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
int y = Add1(1);
|
||||
if (y == 2) return Pass;
|
||||
else return Fail;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ IF "%ErrorCode%"=="100" (
|
||||
echo %~n0: pass
|
||||
EXIT /b 0
|
||||
) ELSE (
|
||||
echo %~n0: fail
|
||||
echo %~n0: fail - %ErrorCode%
|
||||
EXIT /b 1
|
||||
)
|
||||
endlocal
|
||||
|
||||
@@ -3,15 +3,70 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
class Program
|
||||
{
|
||||
public const int Pass = 100;
|
||||
public const int Fail = -1;
|
||||
|
||||
static int Main()
|
||||
{
|
||||
SimpleReadWriteThreadStaticTest.Run(42, "SimpleReadWriteThreadStatic");
|
||||
|
||||
// TODO: After issue https://github.com/dotnet/corert/issues/2695 is fixed, move FinalizeTest to run at the end
|
||||
if (FinalizeTest.Run() != Pass)
|
||||
return Fail;
|
||||
|
||||
ThreadStaticsTestWithTasks.Run();
|
||||
return 100;
|
||||
|
||||
if (ThreadTest.Run() != Pass)
|
||||
return Fail;
|
||||
|
||||
return Pass;
|
||||
}
|
||||
|
||||
public static bool IsRunnningOnWindows()
|
||||
{
|
||||
// Note: Environment.OSVersion is not yet available.
|
||||
// This is a temporary hack that allows to skip Task related tests on Unix.
|
||||
return System.IO.Path.DirectorySeparatorChar == '\\';
|
||||
}
|
||||
}
|
||||
|
||||
class FinalizeTest
|
||||
{
|
||||
public static bool visited = false;
|
||||
public class Dummy
|
||||
{
|
||||
~Dummy()
|
||||
{
|
||||
FinalizeTest.visited = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static int Run()
|
||||
{
|
||||
int iterationCount = 0;
|
||||
while (!visited && iterationCount++ < 10000)
|
||||
{
|
||||
GC.KeepAlive(new Dummy());
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
if (visited)
|
||||
{
|
||||
Console.WriteLine("FinalizeTest passed");
|
||||
return Program.Pass;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("FinalizeTest failed");
|
||||
return Program.Fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +163,12 @@ class ThreadStaticsTestWithTasks
|
||||
|
||||
public static void Run()
|
||||
{
|
||||
if (!Program.IsRunnningOnWindows())
|
||||
{
|
||||
// Tasks are not supported on Unix yet
|
||||
return;
|
||||
}
|
||||
|
||||
Task[] tasks = new Task[TotalTaskCount];
|
||||
for (int i = 0; i < tasks.Length; ++i)
|
||||
{
|
||||
@@ -137,3 +198,381 @@ class ThreadStaticsTestWithTasks
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ThreadTest
|
||||
{
|
||||
private static readonly List<Thread> s_startedThreads = new List<Thread>();
|
||||
|
||||
private static int s_passed;
|
||||
private static int s_failed;
|
||||
|
||||
private static void Expect(bool condition, string message)
|
||||
{
|
||||
if (condition)
|
||||
{
|
||||
Interlocked.Increment(ref s_passed);
|
||||
}
|
||||
else
|
||||
{
|
||||
Interlocked.Increment(ref s_failed);
|
||||
Console.WriteLine("ERROR: " + message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ExpectException<T>(Action action, string message)
|
||||
{
|
||||
Exception ex = null;
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ex = e;
|
||||
}
|
||||
|
||||
if (!(ex is T))
|
||||
{
|
||||
message += string.Format(" (caught {0})", (ex == null) ? "no exception" : ex.GetType().Name);
|
||||
}
|
||||
Expect(ex is T, message);
|
||||
}
|
||||
|
||||
private static void ExpectPassed(string testName, int expectedPassed)
|
||||
{
|
||||
// Wait for all started threads to finish execution
|
||||
foreach (Thread t in s_startedThreads)
|
||||
{
|
||||
t.Join();
|
||||
}
|
||||
|
||||
s_startedThreads.Clear();
|
||||
|
||||
Expect(s_passed == expectedPassed, string.Format("{0}: Expected s_passed == {1}, got {2}", testName, expectedPassed, s_passed));
|
||||
s_passed = 0;
|
||||
}
|
||||
|
||||
private static void TestStartMethod()
|
||||
{
|
||||
// Case 1: new Thread(ThreadStart).Start()
|
||||
var t1 = new Thread(() => Expect(true, "Expected t1 to start"));
|
||||
t1.Start();
|
||||
s_startedThreads.Add(t1);
|
||||
|
||||
// Case 2: new Thread(ThreadStart).Start(parameter)
|
||||
var t2 = new Thread(() => Expect(false, "This thread must not be started"));
|
||||
// InvalidOperationException: The thread was created with a ThreadStart delegate that does not accept a parameter.
|
||||
ExpectException<InvalidOperationException>(() => t2.Start(null), "Expected InvalidOperationException for t2.Start()");
|
||||
|
||||
// Case 3: new Thread(ParameterizedThreadStart).Start()
|
||||
var t3 = new Thread(obj => Expect(obj == null, "Expected obj == null"));
|
||||
t3.Start();
|
||||
s_startedThreads.Add(t3);
|
||||
|
||||
// Case 4: new Thread(ParameterizedThreadStart).Start(parameter)
|
||||
var t4 = new Thread(obj => Expect((int)obj == 42, "Expected (int)obj == 42"));
|
||||
t4.Start(42);
|
||||
s_startedThreads.Add(t4);
|
||||
|
||||
// Start an unstarted resurrected thread.
|
||||
// CoreCLR: ThreadStateException, CoreRT: no exception.
|
||||
Thread unstartedResurrected = Resurrector.CreateUnstartedResurrected();
|
||||
unstartedResurrected.Start();
|
||||
s_startedThreads.Add(unstartedResurrected);
|
||||
|
||||
// Threads cannot started more than once
|
||||
t1.Join();
|
||||
ExpectException<ThreadStateException>(() => t1.Start(), "Expected ThreadStateException for t1.Start()");
|
||||
|
||||
ExpectException<ThreadStateException>(() => Thread.CurrentThread.Start(),
|
||||
"Expected ThreadStateException for CurrentThread.Start()");
|
||||
|
||||
Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();
|
||||
ExpectException<ThreadStateException>(() => stoppedResurrected.Start(),
|
||||
"Expected ThreadStateException for stoppedResurrected.Start()");
|
||||
|
||||
ExpectPassed(nameof(TestStartMethod), 7);
|
||||
}
|
||||
|
||||
private static void TestJoinMethod()
|
||||
{
|
||||
var t = new Thread(() => { });
|
||||
ExpectException<InvalidOperationException>(() => t.Start(null), "Expected InvalidOperationException for t.Start()");
|
||||
ExpectException<ThreadStateException>(() => t.Join(), "Expected ThreadStateException for t.Join()");
|
||||
|
||||
Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();
|
||||
Expect(stoppedResurrected.Join(1), "Expected stoppedResurrected.Join(1) to return true");
|
||||
|
||||
Expect(!Thread.CurrentThread.Join(1), "Expected CurrentThread.Join(1) to return false");
|
||||
|
||||
ExpectPassed(nameof(TestJoinMethod), 4);
|
||||
}
|
||||
|
||||
private static void TestCurrentThreadProperty()
|
||||
{
|
||||
Thread t = null;
|
||||
t = new Thread(() => Expect(Thread.CurrentThread == t, "Expected CurrentThread == t on thread t"));
|
||||
t.Start();
|
||||
s_startedThreads.Add(t);
|
||||
|
||||
Expect(Thread.CurrentThread != t, "Expected CurrentThread != t on main thread");
|
||||
|
||||
ExpectPassed(nameof(TestCurrentThreadProperty), 2);
|
||||
}
|
||||
|
||||
private static void TestNameProperty()
|
||||
{
|
||||
var t = new Thread(() => { });
|
||||
|
||||
t.Name = null;
|
||||
// It is OK to set the null Name multiple times
|
||||
t.Name = null;
|
||||
Expect(t.Name == null, "Expected t.Name == null");
|
||||
|
||||
const string ThreadName = "My thread";
|
||||
t.Name = ThreadName;
|
||||
Expect(t.Name == ThreadName, string.Format("Expected t.Name == \"{0}\"", ThreadName));
|
||||
ExpectException<InvalidOperationException>(() => { t.Name = null; },
|
||||
"Expected InvalidOperationException setting Thread.Name back to null");
|
||||
|
||||
ExpectPassed(nameof(TestNameProperty), 3);
|
||||
}
|
||||
|
||||
private static void TestIsBackgroundProperty()
|
||||
{
|
||||
if (!Program.IsRunnningOnWindows())
|
||||
{
|
||||
// This test uses tasks which are not supported on Unix yet
|
||||
return;
|
||||
}
|
||||
|
||||
// Thread created using Thread.Start
|
||||
var t_event = new AutoResetEvent(false);
|
||||
var t = new Thread(() => t_event.WaitOne());
|
||||
|
||||
t.Start();
|
||||
s_startedThreads.Add(t);
|
||||
|
||||
Expect(!t.IsBackground, "Expected t.IsBackground == false");
|
||||
t_event.Set();
|
||||
t.Join();
|
||||
ExpectException<ThreadStateException>(() => Console.WriteLine(t.IsBackground),
|
||||
"Expected ThreadStateException for t.IsBackground");
|
||||
|
||||
// Thread pool thread
|
||||
Task.Factory.StartNew(() => Expect(Thread.CurrentThread.IsBackground, "Expected IsBackground == true")).Wait();
|
||||
|
||||
// Resurrected threads
|
||||
Thread unstartedResurrected = Resurrector.CreateUnstartedResurrected();
|
||||
Expect(unstartedResurrected.IsBackground == false, "Expected unstartedResurrected.IsBackground == false");
|
||||
|
||||
Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();
|
||||
ExpectException<ThreadStateException>(() => Console.WriteLine(stoppedResurrected.IsBackground),
|
||||
"Expected ThreadStateException for stoppedResurrected.IsBackground");
|
||||
|
||||
// Main thread
|
||||
Expect(!Thread.CurrentThread.IsBackground, "Expected CurrentThread.IsBackground == false");
|
||||
|
||||
ExpectPassed(nameof(TestIsBackgroundProperty), 6);
|
||||
}
|
||||
|
||||
private static void TestIsThreadPoolThreadProperty()
|
||||
{
|
||||
#if false // The IsThreadPoolThread property is not in the contract version we compile against at present
|
||||
var t = new Thread(() => { });
|
||||
|
||||
Expect(!t.IsThreadPoolThread, "Expected t.IsThreadPoolThread == false");
|
||||
Task.Factory.StartNew(() => Expect(Thread.CurrentThread.IsThreadPoolThread, "Expected IsThreadPoolThread == true")).Wait();
|
||||
Expect(!Thread.CurrentThread.IsThreadPoolThread, "Expected CurrentThread.IsThreadPoolThread == false");
|
||||
|
||||
ExpectPassed(nameof(TestIsThreadPoolThreadProperty), 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void TestManagedThreadIdProperty()
|
||||
{
|
||||
int t_id = 0;
|
||||
var t = new Thread(() => {
|
||||
Expect(Thread.CurrentThread.ManagedThreadId == t_id, "Expected CurrentTread.ManagedThreadId == t_id on thread t");
|
||||
Expect(Environment.CurrentManagedThreadId == t_id, "Expected Environment.CurrentManagedThreadId == t_id on thread t");
|
||||
});
|
||||
|
||||
t_id = t.ManagedThreadId;
|
||||
Expect(t_id != 0, "Expected t_id != 0");
|
||||
Expect(Thread.CurrentThread.ManagedThreadId != t_id, "Expected CurrentTread.ManagedThreadId != t_id on main thread");
|
||||
Expect(Environment.CurrentManagedThreadId != t_id, "Expected Environment.CurrentManagedThreadId != t_id on main thread");
|
||||
|
||||
t.Start();
|
||||
s_startedThreads.Add(t);
|
||||
|
||||
// Resurrected threads
|
||||
Thread unstartedResurrected = Resurrector.CreateUnstartedResurrected();
|
||||
Expect(unstartedResurrected.ManagedThreadId != 0, "Expected unstartedResurrected.ManagedThreadId != 0");
|
||||
|
||||
Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();
|
||||
Expect(stoppedResurrected.ManagedThreadId != 0, "Expected stoppedResurrected.ManagedThreadId != 0");
|
||||
|
||||
ExpectPassed(nameof(TestManagedThreadIdProperty), 7);
|
||||
}
|
||||
|
||||
private static void TestThreadStateProperty()
|
||||
{
|
||||
var t_event = new AutoResetEvent(false);
|
||||
var t = new Thread(() => t_event.WaitOne());
|
||||
|
||||
Expect(t.ThreadState == ThreadState.Unstarted, "Expected t.ThreadState == ThreadState.Unstarted");
|
||||
t.Start();
|
||||
s_startedThreads.Add(t);
|
||||
|
||||
Expect(t.ThreadState == ThreadState.Running || t.ThreadState == ThreadState.WaitSleepJoin,
|
||||
"Expected t.ThreadState is either ThreadState.Running or ThreadState.WaitSleepJoin");
|
||||
t_event.Set();
|
||||
t.Join();
|
||||
Expect(t.ThreadState == ThreadState.Stopped, "Expected t.ThreadState == ThreadState.Stopped");
|
||||
|
||||
// Resurrected threads
|
||||
Thread unstartedResurrected = Resurrector.CreateUnstartedResurrected();
|
||||
Expect(unstartedResurrected.ThreadState == ThreadState.Unstarted,
|
||||
"Expected unstartedResurrected.ThreadState == ThreadState.Unstarted");
|
||||
|
||||
Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();
|
||||
Expect(stoppedResurrected.ThreadState == ThreadState.Stopped,
|
||||
"Expected stoppedResurrected.ThreadState == ThreadState.Stopped");
|
||||
|
||||
ExpectPassed(nameof(TestThreadStateProperty), 5);
|
||||
}
|
||||
|
||||
private static unsafe void DoStackAlloc(int size)
|
||||
{
|
||||
byte* buffer = stackalloc byte[size];
|
||||
Volatile.Write(ref buffer[0], 0);
|
||||
}
|
||||
|
||||
private static void TestMaxStackSize()
|
||||
{
|
||||
#if false // The constructors with maxStackSize are not in the contract version we compile against at present
|
||||
// Allocate a 3 MiB buffer on the 4 MiB stack
|
||||
var t = new Thread(() => DoStackAlloc(3 << 20), 4 << 20);
|
||||
t.Start();
|
||||
s_startedThreads.Add(t);
|
||||
#endif
|
||||
|
||||
ExpectPassed(nameof(TestMaxStackSize), 0);
|
||||
}
|
||||
|
||||
static int s_startedThreadCount = 0;
|
||||
private static void TestStartShutdown()
|
||||
{
|
||||
Thread[] threads = new Thread[2048];
|
||||
|
||||
// Creating a large number of threads
|
||||
for (int i = 0; i < threads.Length; i++)
|
||||
{
|
||||
threads[i] = new Thread(() => { Interlocked.Increment(ref s_startedThreadCount); });
|
||||
threads[i].Start();
|
||||
}
|
||||
|
||||
// Wait for all threads to shutdown;
|
||||
for (int i = 0; i < threads.Length; i++)
|
||||
{
|
||||
threads[i].Join();
|
||||
}
|
||||
|
||||
Expect(s_startedThreadCount == threads.Length,
|
||||
String.Format("Not all threads completed. Expected: {0}, Actual: {1}", threads.Length, s_startedThreadCount));
|
||||
}
|
||||
|
||||
public static int Run()
|
||||
{
|
||||
TestStartMethod();
|
||||
TestJoinMethod();
|
||||
|
||||
TestCurrentThreadProperty();
|
||||
TestNameProperty();
|
||||
TestIsBackgroundProperty();
|
||||
TestIsThreadPoolThreadProperty();
|
||||
TestManagedThreadIdProperty();
|
||||
TestThreadStateProperty();
|
||||
|
||||
TestMaxStackSize();
|
||||
TestStartShutdown();
|
||||
|
||||
return (s_failed == 0) ? Program.Pass : Program.Fail;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates resurrected Thread objects.
|
||||
/// </summary>
|
||||
class Resurrector
|
||||
{
|
||||
static Thread s_unstartedResurrected;
|
||||
static Thread s_stoppedResurrected;
|
||||
|
||||
bool _unstarted;
|
||||
Thread _thread = new Thread(() => { });
|
||||
|
||||
Resurrector(bool unstarted)
|
||||
{
|
||||
_unstarted = unstarted;
|
||||
if (!unstarted)
|
||||
{
|
||||
_thread.Start();
|
||||
_thread.Join();
|
||||
}
|
||||
}
|
||||
|
||||
~Resurrector()
|
||||
{
|
||||
if (_unstarted && (s_unstartedResurrected == null))
|
||||
{
|
||||
s_unstartedResurrected = _thread;
|
||||
}
|
||||
else if(!_unstarted && (s_stoppedResurrected == null))
|
||||
{
|
||||
s_stoppedResurrected = _thread;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
static void CreateInstance(bool unstarted)
|
||||
{
|
||||
GC.KeepAlive(new Resurrector(unstarted));
|
||||
}
|
||||
|
||||
static Thread CreateResurrectedThread(ref Thread trap, bool unstarted)
|
||||
{
|
||||
trap = null;
|
||||
|
||||
while (trap == null)
|
||||
{
|
||||
// Call twice to override the address of the first allocation on the stack (for conservative GC)
|
||||
CreateInstance(unstarted);
|
||||
CreateInstance(unstarted);
|
||||
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
}
|
||||
|
||||
// We would like to get a Thread object with its internal SafeHandle member disposed.
|
||||
// The current implementation of SafeHandle postpones disposing until the next garbage
|
||||
// collection. For this reason we do a couple more collections.
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
}
|
||||
|
||||
return trap;
|
||||
}
|
||||
|
||||
public static Thread CreateUnstartedResurrected()
|
||||
{
|
||||
return CreateResurrectedThread(ref s_unstartedResurrected, unstarted: true);
|
||||
}
|
||||
|
||||
public static Thread CreateStoppedResurrected()
|
||||
{
|
||||
return CreateResurrectedThread(ref s_stoppedResurrected, unstarted: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0
external/corert/tests/src/Simple/BasicThreading/BasicThreading.sh
vendored
Normal file → Executable file
0
external/corert/tests/src/Simple/BasicThreading/BasicThreading.sh
vendored
Normal file → Executable file
@@ -1,9 +1,5 @@
|
||||
<Project ToolsVersion="14.0" DefaultTargets="BuildAllFrameworkLibraries" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<PropertyGroup>
|
||||
<NativeIntermediateOutputPath>$(MSBuildProjectDirectory)\obj\$(Configuration)\native\</NativeIntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\..\..\..\src\BuildIntegration\BuildFrameworkNativeObjects.proj" />
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -6,7 +6,7 @@ IF "%ErrorCode%"=="100" (
|
||||
echo %~n0: pass
|
||||
EXIT /b 0
|
||||
) ELSE (
|
||||
echo %~n0: fail
|
||||
echo %~n0: fail - %ErrorCode%
|
||||
EXIT /b 1
|
||||
)
|
||||
endlocal
|
||||
|
||||
@@ -6,7 +6,7 @@ IF "%ErrorCode%"=="100" (
|
||||
echo %~n0: pass
|
||||
EXIT /b 0
|
||||
) ELSE (
|
||||
echo %~n0: fail
|
||||
echo %~n0: fail - %ErrorCode%
|
||||
EXIT /b 1
|
||||
)
|
||||
endlocal
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// 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;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
private static int Main(string[] args)
|
||||
{
|
||||
string s123 = 123.ToString();
|
||||
if (s123 != "123")
|
||||
{
|
||||
Console.WriteLine("Unexpected: " + s123);
|
||||
return 1;
|
||||
}
|
||||
|
||||
string s123dot5 = (123.5).ToString(CultureInfo.InvariantCulture);
|
||||
if (s123dot5 != "123.5")
|
||||
{
|
||||
Console.WriteLine("Unexpected: " + s123dot5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Console.WriteLine("{0}", "Hi");
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ IF "%ErrorCode%"=="100" (
|
||||
echo %~n0: pass
|
||||
EXIT /b 0
|
||||
) ELSE (
|
||||
echo %~n0: fail
|
||||
echo %~n0: fail - %ErrorCode%
|
||||
EXIT /b 1
|
||||
)
|
||||
endlocal
|
||||
|
||||
1034
external/corert/tests/src/Simple/Generics/Generics.cs
vendored
1034
external/corert/tests/src/Simple/Generics/Generics.cs
vendored
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ IF "%ErrorCode%"=="0" (
|
||||
echo %~n0: pass
|
||||
EXIT /b 0
|
||||
) ELSE (
|
||||
echo %~n0: fail
|
||||
echo %~n0: fail - %ErrorCode%
|
||||
EXIT /b 1
|
||||
)
|
||||
endlocal
|
||||
|
||||
@@ -6,7 +6,7 @@ IF "%ErrorCode%"=="100" (
|
||||
echo %~n0: pass
|
||||
EXIT /b 0
|
||||
) ELSE (
|
||||
echo %~n0: fail
|
||||
echo %~n0: fail - %ErrorCode%
|
||||
EXIT /b 1
|
||||
)
|
||||
endlocal
|
||||
|
||||
@@ -25,6 +25,9 @@ public class BringUpTest
|
||||
if (TestVariantInterfaces() == Fail)
|
||||
return Fail;
|
||||
|
||||
if (TestSpecialArrayInterfaces() == Fail)
|
||||
return Fail;
|
||||
|
||||
return Pass;
|
||||
}
|
||||
|
||||
@@ -337,5 +340,23 @@ public class BringUpTest
|
||||
return Pass;
|
||||
}
|
||||
|
||||
class SpecialArrayBase { }
|
||||
class SpecialArrayDerived : SpecialArrayBase { }
|
||||
|
||||
// NOTE: ICollection is not a variant interface, but arrays can cast with it as if it was
|
||||
static ICollection<SpecialArrayBase> s_specialDerived = new SpecialArrayDerived[42];
|
||||
static ICollection<uint> s_specialInt = (ICollection<uint>)(object)new int[85];
|
||||
|
||||
private static int TestSpecialArrayInterfaces()
|
||||
{
|
||||
if (s_specialDerived.Count != 42)
|
||||
return Fail;
|
||||
|
||||
if (s_specialInt.Count != 85)
|
||||
return Fail;
|
||||
|
||||
return Pass;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
67
external/corert/tests/src/Simple/MultiModule/Library.cs
vendored
Normal file
67
external/corert/tests/src/Simple/MultiModule/Library.cs
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
// 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.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
public class MultiModuleLibrary
|
||||
{
|
||||
// Do not reference these three (3) statics in this assembly.
|
||||
// We're testing that statics in library code are rooted for use by consuming application code.
|
||||
public static int ReturnValue;
|
||||
public static string StaticString;
|
||||
[ThreadStatic]
|
||||
public static int ThreadStaticInt;
|
||||
|
||||
public static bool MethodThatUsesGenerics()
|
||||
{
|
||||
// Force the existence of a generic dictionary for GenericClass<string>
|
||||
// It's important we only use one canonical method and that method is not used from the consumption EXE.
|
||||
if (GenericClass<string>.IsArrayOfT(null))
|
||||
return false;
|
||||
if (!GenericClass<string>.IsArrayOfT(new string[0]))
|
||||
return false;
|
||||
|
||||
// Force the existence of a generic dictionary for GenericClass<GenericStruct<string>>
|
||||
// Here we test a canonical method that will be used from the consumption EXE too.
|
||||
if (!GenericClass<GenericStruct<string>>.IsT(new GenericStruct<string>()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public class GenericClass<T>
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static bool IsT(object o) => o is T;
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static bool IsArrayOfT(object o) => o is T[];
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static bool IsMdArrayOfT(object o) => o is T[,];
|
||||
}
|
||||
|
||||
public struct GenericStruct<T>
|
||||
{
|
||||
public T Value;
|
||||
}
|
||||
|
||||
public class GenericClassWithTLS<T>
|
||||
{
|
||||
[ThreadStatic]
|
||||
public static int ThreadStaticInt;
|
||||
}
|
||||
|
||||
public static bool MethodThatUsesGenericWithTLS()
|
||||
{
|
||||
GenericClassWithTLS<int>.ThreadStaticInt += 1;
|
||||
return GenericClassWithTLS<int>.ThreadStaticInt == 1;
|
||||
}
|
||||
|
||||
public enum MyEnum
|
||||
{
|
||||
One, Two
|
||||
}
|
||||
}
|
||||
10
external/corert/tests/src/Simple/MultiModule/Library.csproj
vendored
Normal file
10
external/corert/tests/src/Simple/MultiModule/Library.csproj
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<Project DefaultTargets="Build;IlcCompile" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<IlcMultiModule>true</IlcMultiModule>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Library.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), SimpleTest.targets))\SimpleTest.targets" />
|
||||
</Project>
|
||||
91
external/corert/tests/src/Simple/MultiModule/MultiModule.cs
vendored
Normal file
91
external/corert/tests/src/Simple/MultiModule/MultiModule.cs
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// 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.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
public class ReflectionTest
|
||||
{
|
||||
const int Pass = 100;
|
||||
const int Fail = -1;
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
if (TestStaticBases() == Fail)
|
||||
return Fail;
|
||||
|
||||
if (TestSharedGenerics() == Fail)
|
||||
return Fail;
|
||||
|
||||
if (TestGenericTLS() == Fail)
|
||||
return Fail;
|
||||
|
||||
if (TestInjectedEnumMethods() == Fail)
|
||||
return Fail;
|
||||
|
||||
return Pass;
|
||||
}
|
||||
|
||||
public static int TestStaticBases()
|
||||
{
|
||||
Console.WriteLine("Testing static bases in library code are available..");
|
||||
MultiModuleLibrary.ReturnValue = 50;
|
||||
MultiModuleLibrary.ThreadStaticInt = 50;
|
||||
|
||||
MultiModuleLibrary.StaticString = MultiModuleLibrary.ReturnValue.ToString() + MultiModuleLibrary.ThreadStaticInt.ToString();
|
||||
if (MultiModuleLibrary.StaticString != "5050")
|
||||
return Fail;
|
||||
|
||||
if (MultiModuleLibrary.ReturnValue + MultiModuleLibrary.ThreadStaticInt != 100)
|
||||
return Fail;
|
||||
|
||||
return Pass;
|
||||
}
|
||||
|
||||
public static int TestSharedGenerics()
|
||||
{
|
||||
Console.WriteLine("Testing generic dictionaries can be folded properly..");
|
||||
|
||||
// Use a generic dictionary that also exists in the library
|
||||
if (!MultiModuleLibrary.GenericClass<string>.IsT("Hello"))
|
||||
return Fail;
|
||||
if (!MultiModuleLibrary.GenericClass<string>.IsMdArrayOfT(new string[0, 0]))
|
||||
return Fail;
|
||||
|
||||
if (!MultiModuleLibrary.GenericClass<MultiModuleLibrary.GenericStruct<string>>.IsArrayOfT(new MultiModuleLibrary.GenericStruct<string>[0]))
|
||||
return Fail;
|
||||
if (!MultiModuleLibrary.GenericClass<MultiModuleLibrary.GenericStruct<string>>.IsT(new MultiModuleLibrary.GenericStruct<string>()))
|
||||
return Fail;
|
||||
|
||||
if (!MultiModuleLibrary.MethodThatUsesGenerics())
|
||||
return Fail;
|
||||
|
||||
return Pass;
|
||||
}
|
||||
|
||||
public static int TestGenericTLS()
|
||||
{
|
||||
Console.WriteLine("Testing thread statics on generic types shared between modules are shared properly..");
|
||||
|
||||
if (!MultiModuleLibrary.MethodThatUsesGenericWithTLS())
|
||||
return Fail;
|
||||
|
||||
MultiModuleLibrary.GenericClassWithTLS<int>.ThreadStaticInt += 1;
|
||||
if (MultiModuleLibrary.GenericClassWithTLS<int>.ThreadStaticInt != 2)
|
||||
return Fail;
|
||||
|
||||
return Pass;
|
||||
}
|
||||
|
||||
public static int TestInjectedEnumMethods()
|
||||
{
|
||||
Console.WriteLine("Testing context-injected methods on enums..");
|
||||
if (!MultiModuleLibrary.MyEnum.One.Equals(MultiModuleLibrary.MyEnum.One))
|
||||
return Fail;
|
||||
|
||||
return Pass;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,16 @@
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<PropertyGroup>
|
||||
<IlcMultiModule>true</IlcMultiModule>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="*.cs" />
|
||||
<Compile Include="MultiModule.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="Library.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), SimpleTest.targets))\SimpleTest.targets" />
|
||||
</Project>
|
||||
0
external/corert/tests/src/Simple/Add1/Add1.sh → external/corert/tests/src/Simple/MultiModule/MultiModule.sh
vendored
Executable file → Normal file
0
external/corert/tests/src/Simple/Add1/Add1.sh → external/corert/tests/src/Simple/MultiModule/MultiModule.sh
vendored
Executable file → Normal file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user