diff --git a/src/System.Threading.Thread/tests/DefaultApartmentStateMain/Configurations.props b/src/System.Threading.Thread/tests/DefaultApartmentStateMain/Configurations.props new file mode 100644 index 000000000000..c398e42e8994 --- /dev/null +++ b/src/System.Threading.Thread/tests/DefaultApartmentStateMain/Configurations.props @@ -0,0 +1,8 @@ + + + + + netstandard; + + + \ No newline at end of file diff --git a/src/System.Threading.Thread/tests/DefaultApartmentStateMain/DefaultApartmentStateMain.cs b/src/System.Threading.Thread/tests/DefaultApartmentStateMain/DefaultApartmentStateMain.cs new file mode 100644 index 000000000000..10df29f29375 --- /dev/null +++ b/src/System.Threading.Thread/tests/DefaultApartmentStateMain/DefaultApartmentStateMain.cs @@ -0,0 +1,61 @@ +// 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.Threading; + +namespace DefaultApartmentStateMain +{ + internal static class DefaultApartmentStateMain + { + private const int Success = 0; + private const int SuccessOnUnix = 2; + private const int Failure = 1; + + private static Thread s_mainThread; + + static int Main(string[] args) + { + string testName = args[0]; + s_mainThread = Thread.CurrentThread; + + switch (testName) + { + case "GetApartmentStateTest": + return GetApartmentStateTest(); + case "SetApartmentStateTest": + return SetApartmentStateTest(); + default: + return Failure; + } + } + + private static int GetApartmentStateTest() + { + if (s_mainThread.GetApartmentState() == ApartmentState.MTA) + { + s_mainThread.SetApartmentState(ApartmentState.MTA); + return Success; + } + return SuccessOnUnix; + } + + private static int SetApartmentStateTest() + { + try + { + s_mainThread.SetApartmentState(ApartmentState.STA); + } + catch (InvalidOperationException) + { + return Success; + } + catch (PlatformNotSupportedException) + { + return SuccessOnUnix; + } + return Failure; + } + } +} diff --git a/src/System.Threading.Thread/tests/DefaultApartmentStateMain/DefaultApartmentStateMain.csproj b/src/System.Threading.Thread/tests/DefaultApartmentStateMain/DefaultApartmentStateMain.csproj new file mode 100644 index 000000000000..c739fb3e16ec --- /dev/null +++ b/src/System.Threading.Thread/tests/DefaultApartmentStateMain/DefaultApartmentStateMain.csproj @@ -0,0 +1,19 @@ + + + Exe + true + {32432E07-5CA4-41F3-9855-22AB1F1E69B3} + netstandard-Debug;netstandard-Release + + + + + + + PreserveNewest + + + PreserveNewest + + + \ No newline at end of file diff --git a/src/System.Threading.Thread/tests/DefaultApartmentStateMain/DefaultApartmentStateMain.exe.config b/src/System.Threading.Thread/tests/DefaultApartmentStateMain/DefaultApartmentStateMain.exe.config new file mode 100644 index 000000000000..b955a1b9b2c4 --- /dev/null +++ b/src/System.Threading.Thread/tests/DefaultApartmentStateMain/DefaultApartmentStateMain.exe.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/System.Threading.Thread/tests/DefaultApartmentStateMain/DefaultApartmentStateMain.runtimeconfig.json b/src/System.Threading.Thread/tests/DefaultApartmentStateMain/DefaultApartmentStateMain.runtimeconfig.json new file mode 100644 index 000000000000..0e7c179be9d8 --- /dev/null +++ b/src/System.Threading.Thread/tests/DefaultApartmentStateMain/DefaultApartmentStateMain.runtimeconfig.json @@ -0,0 +1,8 @@ +{ + "runtimeOptions": { + "framework": { + "name": "Microsoft.NETCore.App", + "version": "9.9.9" + } + } +} \ No newline at end of file diff --git a/src/System.Threading.Thread/tests/MTAMain/MTAMain.cs b/src/System.Threading.Thread/tests/MTAMain/MTAMain.cs index fa25b067fd3e..5907fab5f0a3 100644 --- a/src/System.Threading.Thread/tests/MTAMain/MTAMain.cs +++ b/src/System.Threading.Thread/tests/MTAMain/MTAMain.cs @@ -9,46 +9,54 @@ namespace MTAMain { internal static class MTAMain { + private const int Success = 0; + private const int SuccessOnUnix = 2; + private const int Failure = 1; + + private static Thread s_mainThread; + [MTAThread] static int Main(string[] args) { - const int Success = 0; - const int SuccessOnUnix = 2; - const int Failure = 1; + string testName = args[0]; + s_mainThread = Thread.CurrentThread; - string mode = args[0]; - int retValue = Failure; - Thread curThread = Thread.CurrentThread; - - if (mode == "GetApartmentState") + switch (testName) { - if (curThread.GetApartmentState() == ApartmentState.MTA) - { - curThread.SetApartmentState(ApartmentState.MTA); - retValue = Success; - } - else - { - retValue = SuccessOnUnix; - } + case "GetApartmentStateTest": + return GetApartmentStateTest(); + case "SetApartmentStateTest": + return SetApartmentStateTest(); + default: + return Failure; } - else + } + + private static int GetApartmentStateTest() + { + if (s_mainThread.GetApartmentState() == ApartmentState.MTA) { - try - { - curThread.SetApartmentState(ApartmentState.STA); - } - catch (InvalidOperationException) - { - retValue = Success; - } - catch (PlatformNotSupportedException) - { - retValue = SuccessOnUnix; - } + s_mainThread.SetApartmentState(ApartmentState.MTA); + return Success; } + return SuccessOnUnix; + } - return retValue; + private static int SetApartmentStateTest() + { + try + { + s_mainThread.SetApartmentState(ApartmentState.STA); + } + catch (InvalidOperationException) + { + return Success; + } + catch (PlatformNotSupportedException) + { + return SuccessOnUnix; + } + return Failure; } } } diff --git a/src/System.Threading.Thread/tests/STAMain/STAMain.cs b/src/System.Threading.Thread/tests/STAMain/STAMain.cs index 410211175b63..f7045516e706 100644 --- a/src/System.Threading.Thread/tests/STAMain/STAMain.cs +++ b/src/System.Threading.Thread/tests/STAMain/STAMain.cs @@ -9,46 +9,94 @@ namespace STAMain { internal static class STAMain { + private const int Success = 0; + private const int SuccessOnUnix = 2; + private const int Failure = 1; + + private static Thread s_mainThread; + [STAThread] static int Main(string[] args) { - const int Success = 0; - const int SuccessOnUnix = 2; - const int Failure = 1; - - string mode = args[0]; - int retValue = Failure; - Thread curThread = Thread.CurrentThread; - - if (mode == "GetApartmentState") - { - if (curThread.GetApartmentState() == ApartmentState.STA) - { - curThread.SetApartmentState(ApartmentState.STA); - retValue = Success; - } - else - { - retValue = SuccessOnUnix; - } - } - else - { - try - { - curThread.SetApartmentState(ApartmentState.MTA); - } - catch (InvalidOperationException) - { - retValue = Success; - } - catch (PlatformNotSupportedException) - { - retValue = SuccessOnUnix; - } - } - - return retValue; + string testName = args[0]; + s_mainThread = Thread.CurrentThread; + + switch (testName) + { + case "GetApartmentStateTest": + return GetApartmentStateTest(); + case "SetApartmentStateTest": + return SetApartmentStateTest(); + case "WaitAllNotSupportedOnSta_Test0": + return WaitAllNotSupportedOnSta_Test0(); + case "WaitAllNotSupportedOnSta_Test1": + return WaitAllNotSupportedOnSta_Test1(); + default: + return Failure; + } + } + + private static int GetApartmentStateTest() + { + if (s_mainThread.GetApartmentState() == ApartmentState.STA) + { + s_mainThread.SetApartmentState(ApartmentState.STA); + return Success; + } + return SuccessOnUnix; + } + + private static int SetApartmentStateTest() + { + try + { + s_mainThread.SetApartmentState(ApartmentState.MTA); + } + catch (InvalidOperationException) + { + return Success; + } + catch (PlatformNotSupportedException) + { + return SuccessOnUnix; + } + return Failure; + } + + private static int WaitAllNotSupportedOnSta_Test0() + { + var wh = new ManualResetEvent[2]; + wh[0] = new ManualResetEvent(true); + wh[1] = new ManualResetEvent(true); + try + { + WaitHandle.WaitAll(wh, 0); + return SuccessOnUnix; + } + catch (NotSupportedException) + { + return Success; + } + } + + private static int WaitAllNotSupportedOnSta_Test1() + { + var wh = new ManualResetEvent[2]; + wh[0] = new ManualResetEvent(true); + wh[1] = wh[0]; + try + { + WaitHandle.WaitAll(wh, 0); + return Failure; + } + catch (NotSupportedException) + { + return Success; + } + catch (DuplicateWaitObjectException) + { + return SuccessOnUnix; + } } } } diff --git a/src/System.Threading.Thread/tests/System.Threading.Thread.Tests.csproj b/src/System.Threading.Thread/tests/System.Threading.Thread.Tests.csproj index 94bec3173959..579bbf7ccbb2 100644 --- a/src/System.Threading.Thread/tests/System.Threading.Thread.Tests.csproj +++ b/src/System.Threading.Thread/tests/System.Threading.Thread.Tests.csproj @@ -27,5 +27,8 @@ MTAMain + + DefaultApartmentStateMain + \ No newline at end of file diff --git a/src/System.Threading.Thread/tests/ThreadTests.cs b/src/System.Threading.Thread/tests/ThreadTests.cs index 779f2883175c..1a2505210995 100644 --- a/src/System.Threading.Thread/tests/ThreadTests.cs +++ b/src/System.Threading.Thread/tests/ThreadTests.cs @@ -156,23 +156,27 @@ private static IEnumerable ApartmentStateTest_MemberData() } [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))] - [InlineData("STAMain.exe", "GetApartmentState")] - [InlineData("STAMain.exe", "SetApartmentState")] - [InlineData("MTAMain.exe", "GetApartmentState")] - [InlineData("MTAMain.exe", "SetApartmentState")] + [InlineData("STAMain.exe", "GetApartmentStateTest")] + [InlineData("STAMain.exe", "SetApartmentStateTest")] + [InlineData("STAMain.exe", "WaitAllNotSupportedOnSta_Test0")] + [InlineData("STAMain.exe", "WaitAllNotSupportedOnSta_Test1")] + [InlineData("MTAMain.exe", "GetApartmentStateTest")] + [InlineData("MTAMain.exe", "SetApartmentStateTest")] + [InlineData("DefaultApartmentStateMain.exe", "GetApartmentStateTest")] + [InlineData("DefaultApartmentStateMain.exe", "SetApartmentStateTest")] [ActiveIssue(20766, TargetFrameworkMonikers.Uap)] - public static void ApartmentState_AttributePresent(string AppName, string mode) + public static void ApartmentState_AttributePresent(string appName, string testName) { var psi = new ProcessStartInfo(); if (PlatformDetection.IsFullFramework || PlatformDetection.IsNetNative) { - psi.FileName = AppName; - psi.Arguments = $"{mode}"; + psi.FileName = appName; + psi.Arguments = $"{testName}"; } else { psi.FileName = DummyClass.HostRunnerTest; - psi.Arguments = $"{AppName} {mode}"; + psi.Arguments = $"{appName} {testName}"; } using (Process p = Process.Start(psi)) { @@ -194,20 +198,6 @@ public static void ApartmentState_NoAttributePresent_DefaultState_Windows() }).Dispose(); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))] - [ActiveIssue(20766,TargetFrameworkMonikers.UapAot)] - [PlatformSpecific(TestPlatforms.Windows)] - [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] - public static void ApartmentState_NoAttributePresent_STA_Windows_Core() - { - DummyClass.RemoteInvoke(() => - { - Thread.CurrentThread.SetApartmentState(ApartmentState.STA); - Assert.Equal(ApartmentState.STA, Thread.CurrentThread.GetApartmentState()); - Assert.Throws(() => Thread.CurrentThread.SetApartmentState(ApartmentState.MTA)); - }).Dispose(); - } - // The Thread Apartment State is set to MTA if attribute is not specified on main function [Fact] [PlatformSpecific(TestPlatforms.Windows)]