Skip to content

Commit

Permalink
Test a couple of fixes for apartment state issues
Browse files Browse the repository at this point in the history
  • Loading branch information
kouvel committed Aug 13, 2018
1 parent e62a4bd commit 3043e42
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 90 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildConfigurations>
netstandard;
</BuildConfigurations>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<ProjectGuid>{32432E07-5CA4-41F3-9855-22AB1F1E69B3}</ProjectGuid>
<Configurations>netstandard-Debug;netstandard-Release</Configurations>
</PropertyGroup>
<ItemGroup>
<Compile Include="DefaultApartmentStateMain.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="DefaultApartmentStateMain.runtimeconfig.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="DefaultApartmentStateMain.exe.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<developmentMode developerInstallation="true" />
</runtime>
</configuration>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"runtimeOptions": {
"framework": {
"name": "Microsoft.NETCore.App",
"version": "9.9.9"
}
}
}
70 changes: 39 additions & 31 deletions src/System.Threading.Thread/tests/MTAMain/MTAMain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
122 changes: 85 additions & 37 deletions src/System.Threading.Thread/tests/STAMain/STAMain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@
<ProjectReference Include="MTAMain\MTAMain.csproj">
<Name>MTAMain</Name>
</ProjectReference>
<ProjectReference Include="DefaultApartmentStateMain\DefaultApartmentStateMain.csproj">
<Name>DefaultApartmentStateMain</Name>
</ProjectReference>
</ItemGroup>
</Project>
34 changes: 12 additions & 22 deletions src/System.Threading.Thread/tests/ThreadTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,23 +156,27 @@ private static IEnumerable<object[]> 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))
{
Expand All @@ -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<InvalidOperationException>(() => 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)]
Expand Down

0 comments on commit 3043e42

Please sign in to comment.