Skip to content

Commit

Permalink
Fix StartInfo test (#44392)
Browse files Browse the repository at this point in the history
* Stabilize StartInfo_NotepadWithContent_withArgumentList

* Add state in failed SetApartmentState exception

* Same for other tests

* Extract common code

* Modify

* Extract common code

* Pass down throwOnError

* Apply suggestions from code review

Co-authored-by: Jan Kotas <[email protected]>

* feedback

* Add process for disposal

* Make slow test outer loop

Co-authored-by: Jan Kotas <[email protected]>
  • Loading branch information
danmoseley and jkotas authored Nov 12, 2020
1 parent 8b3b1b5 commit a207c7f
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ public ApartmentState GetApartmentState() =>
/// single-threaded or multi-threaded apartment.
/// </summary>
#if FEATURE_COMINTEROP_APARTMENT_SUPPORT
private bool TrySetApartmentStateUnchecked(ApartmentState state)
private bool SetApartmentStateUnchecked(ApartmentState state, bool throwOnError)
{
ApartmentState retState = (ApartmentState)SetApartmentStateNative((int)state);

Expand All @@ -433,6 +433,12 @@ private bool TrySetApartmentStateUnchecked(ApartmentState state)

if (retState != state)
{
if (throwOnError)
{
string msg = SR.Format(SR.Thread_ApartmentState_ChangeFailed, retState);
throw new InvalidOperationException(msg);
}

return false;
}

Expand All @@ -445,9 +451,19 @@ private bool TrySetApartmentStateUnchecked(ApartmentState state)
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern int SetApartmentStateNative(int state);
#else // FEATURE_COMINTEROP_APARTMENT_SUPPORT
private static bool TrySetApartmentStateUnchecked(ApartmentState state)
private static bool SetApartmentStateUnchecked(ApartmentState state, bool throwOnError)
{
return state == ApartmentState.Unknown;
if (state != ApartmentState.Unknown)
{
if (throwOnError)
{
throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}

return false;
}

return true;
}
#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -947,11 +947,7 @@ public void StartInfo_NotepadWithContent(bool useShellExecute)

try
{
process.WaitForInputIdle(); // Give the file a chance to load
Assert.Equal("notepad", process.ProcessName);

// On some Windows versions, the file extension is not included in the title
Assert.StartsWith(Path.GetFileNameWithoutExtension(tempFile), process.MainWindowTitle);
VerifyNotepadMainWindowTitle(process, tempFile);
}
finally
{
Expand Down Expand Up @@ -985,18 +981,7 @@ public void StartInfo_TextFile_ShellExecute()

try
{
process.WaitForInputIdle(); // Give the file a chance to load
Assert.Equal("notepad", process.ProcessName);

if (PlatformDetection.IsInAppContainer)
{
Assert.Throws<PlatformNotSupportedException>(() => process.MainWindowTitle);
}
else
{
// On some Windows versions, the file extension is not included in the title
Assert.StartsWith(Path.GetFileNameWithoutExtension(tempFile), process.MainWindowTitle);
}
VerifyNotepadMainWindowTitle(process, tempFile);
}
finally
{
Expand Down Expand Up @@ -1172,17 +1157,38 @@ public void StartInfo_NotepadWithContent_withArgumentList(bool useShellExecute)

try
{
process.WaitForInputIdle(); // Give the file a chance to load
Assert.Equal("notepad", process.ProcessName);

// On some Windows versions, the file extension is not included in the title
Assert.StartsWith(Path.GetFileNameWithoutExtension(tempFile), process.MainWindowTitle);
VerifyNotepadMainWindowTitle(process, tempFile);
}
finally
{
process?.Kill();
}
}
}

private void VerifyNotepadMainWindowTitle(Process process, string filename)
{
// On some Windows versions, the file extension is not included in the title
string expected = Path.GetFileNameWithoutExtension(filename);

process.WaitForInputIdle(); // Give the file a chance to load
Assert.Equal("notepad", process.ProcessName);

// Notepad calls CreateWindowEx with pWindowName of empty string, then calls SetWindowTextW
// with "Untitled - Notepad" then finally if you're opening a file, calls SetWindowTextW
// with something similar to "myfilename - Notepad". So there's a race between input idle
// and the expected MainWindowTitle because of how Notepad is implemented.
string title = process.MainWindowTitle;
int count = 0;
while (!title.StartsWith(expected) && count < 500)
{
Thread.Sleep(10);
process.Refresh();
title = process.MainWindowTitle;
count++;
}

Assert.StartsWith(expected, title);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ public partial class ProcessTestBase : FileCleanupTestBase

protected Process CreateDefaultProcess()
{
if (_process != null)
throw new InvalidOperationException();

_process = CreateProcessLong();
_process.Start();
AddProcessForDispose(_process);
return _process;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ public async Task WaitAsyncForSelfTerminatingChild()
}

[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[OuterLoop("As written, takes 30 seconds")]
public async Task WaitAsyncForProcess()
{
Process p = CreateSleepProcess(WaitInMS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3440,7 +3440,7 @@
<value>An attempt was made to transition a task to a final state when it had already completed.</value>
</data>
<data name="Thread_ApartmentState_ChangeFailed" xml:space="preserve">
<value>Failed to set the specified COM apartment state.</value>
<value>Failed to set the specified COM apartment state. Current apartment state '{0}'.</value>
</data>
<data name="Thread_GetSetCompressedStack_NotSupported" xml:space="preserve">
<value>Use CompressedStack.(Capture/Run) instead.</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1623,7 +1623,6 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshal.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\StandardOleMarshalObject.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Security\SecureString.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Thread.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\LowLevelMonitor.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\TimerQueue.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\TimeZoneInfo.Win32.cs" />
Expand Down Expand Up @@ -1829,7 +1828,6 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\StandardOleMarshalObject.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Security\SecureString.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\LowLevelMonitor.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Thread.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\TimerQueue.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\TimeZoneInfo.Unix.cs" />
</ItemGroup>
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -295,13 +295,15 @@ public ApartmentState ApartmentState
[SupportedOSPlatform("windows")]
public void SetApartmentState(ApartmentState state)
{
if (!TrySetApartmentState(state))
{
throw GetApartmentStateChangeFailedException();
}
SetApartmentState(state, throwOnError:true);
}

public bool TrySetApartmentState(ApartmentState state)
{
return SetApartmentState(state, throwOnError:false);
}

private bool SetApartmentState(ApartmentState state, bool throwOnError)
{
switch (state)
{
Expand All @@ -314,7 +316,7 @@ public bool TrySetApartmentState(ApartmentState state)
throw new ArgumentOutOfRangeException(nameof(state), SR.ArgumentOutOfRange_Enum);
}

return TrySetApartmentStateUnchecked(state);
return SetApartmentStateUnchecked(state, throwOnError);
}

[Obsolete("Thread.GetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")]
Expand Down
2 changes: 1 addition & 1 deletion src/libraries/System.Threading.Thread/tests/ThreadTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public static void ApartmentState_NoAttributePresent_DefaultState_Windows()
RemoteExecutor.Invoke(() =>
{
Assert.Equal(ApartmentState.MTA, Thread.CurrentThread.GetApartmentState());
Assert.Throws<InvalidOperationException>(() => Thread.CurrentThread.SetApartmentState(ApartmentState.STA));
AssertExtensions.ThrowsContains<InvalidOperationException>(() => Thread.CurrentThread.SetApartmentState(ApartmentState.STA), "MTA");
Thread.CurrentThread.SetApartmentState(ApartmentState.MTA);
}).Dispose();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,20 @@ public static bool Yield()
return YieldInternal();
}

private static bool TrySetApartmentStateUnchecked(ApartmentState state) => state == ApartmentState.Unknown;
private static bool SetApartmentStateUnchecked(ApartmentState state, bool throwOnError)
{
if (state != ApartmentState.Unknown)
{
if (throwOnError)
{
throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}

return false;
}

return true;
}

private ThreadState ValidateThreadState()
{
Expand Down

0 comments on commit a207c7f

Please sign in to comment.