Fix TestPriorityLevelProperty test (dotnet/corefx#37377)
authorStephen Toub <stoub@microsoft.com>
Fri, 3 May 2019 00:29:58 +0000 (20:29 -0400)
committerGitHub <noreply@github.com>
Fri, 3 May 2019 00:29:58 +0000 (20:29 -0400)
* Fix TestPriorityLevelProperty test

If the target thread goes away between the time we grab it and try to manipulate it, the test fails.  Instead, just create a thread in the current process, as we can then target that one directly and ensure it's always in a good state for testing against.

* Address PR feedback

Commit migrated from https://github.com/dotnet/corefx/commit/dd368445da30401b9dd2290a9612fccf617063b9

src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs [new file with mode: 0644]
src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Windows.cs [new file with mode: 0644]
src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs
src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj

diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Unix.cs
new file mode 100644 (file)
index 0000000..9869514
--- /dev/null
@@ -0,0 +1,35 @@
+// 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.ComponentModel;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Xunit;
+
+namespace System.Diagnostics.Tests
+{
+    public partial class ProcessThreadTests
+    {
+        [PlatformSpecific(TestPlatforms.AnyUnix)]
+        [Fact]
+        public void TestPriorityLevelProperty_Unix()
+        {
+            CreateDefaultProcess();
+
+            ProcessThread thread = _process.Threads[0];
+            ThreadPriorityLevel level = ThreadPriorityLevel.Normal;
+
+            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+            {
+                Assert.Throws<PlatformNotSupportedException>(() => thread.PriorityLevel);
+            }
+            else
+            {
+                level = thread.PriorityLevel;
+            }
+
+            Assert.Throws<PlatformNotSupportedException>(() => thread.PriorityLevel = level);
+        }
+    }
+}
diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Windows.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.Windows.cs
new file mode 100644 (file)
index 0000000..19efc14
--- /dev/null
@@ -0,0 +1,60 @@
+// 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.Threading;
+using System.Linq;
+using Xunit;
+
+namespace System.Diagnostics.Tests
+{
+    public partial class ProcessThreadTests : ProcessTestBase
+    {
+        [PlatformSpecific(TestPlatforms.Windows)] // P/Invokes
+        [Fact]
+        [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "Retrieving information about local processes is not supported on uap")]
+        public void PriorityLevel_Roundtrips()
+        {
+            using (Barrier b = new Barrier(2))
+            using (Process currentProcess = Process.GetCurrentProcess())
+            {
+                int targetThreadId = 0;
+
+                // Launch a thread whose priority we'll manipulate.
+                var t = new Thread(() =>
+                {
+                    targetThreadId = GetCurrentThreadId();
+                    b.SignalAndWait();
+                    b.SignalAndWait(); // wait until the main test is done targeting this thread
+                });
+                t.IsBackground = true;
+                t.Start();
+
+                b.SignalAndWait(); // wait until targetThreadId is valid
+                try
+                {
+                    // Find the relevant ProcessThread in this process
+                    ProcessThread targetThread = currentProcess.Threads.Cast<ProcessThread>().Single(pt => pt.Id == targetThreadId);
+
+                    // Try setting and getting its priority
+                    foreach (ThreadPriorityLevel level in new[] { ThreadPriorityLevel.AboveNormal, ThreadPriorityLevel.BelowNormal, ThreadPriorityLevel.Normal })
+                    {
+                        targetThread.PriorityLevel = ThreadPriorityLevel.AboveNormal;
+                        Assert.Equal(ThreadPriorityLevel.AboveNormal, targetThread.PriorityLevel);
+                    }
+                }
+                finally
+                {
+                    // Allow the thread to exit
+                    b.SignalAndWait();
+                }
+
+                t.Join();
+            }
+        }
+
+        [DllImport("kernel32")]
+        private extern static int GetCurrentThreadId();
+    }
+}
index 0af0365..3edb546 100644 (file)
@@ -11,7 +11,7 @@ using System.Threading.Tasks;
 
 namespace System.Diagnostics.Tests
 {
-    public class ProcessThreadTests : ProcessTestBase
+    public partial class ProcessThreadTests : ProcessTestBase
     {
         [Fact]
         [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "Retrieving information about local processes is not supported on uap")]
@@ -153,7 +153,7 @@ namespace System.Diagnostics.Tests
                 Assert.NotNull(threads);
                 Assert.NotEmpty(threads);
 
-                IntPtr startAddress = threads[0].StartAddress; 
+                IntPtr startAddress = threads[0].StartAddress;
 
                 // There's nothing we can really validate about StartAddress, other than that we can get its value
                 // without throwing.  All values (even zero) are valid on all platforms.
@@ -162,46 +162,6 @@ namespace System.Diagnostics.Tests
 
         [Fact]
         [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "Retrieving information about local processes is not supported on uap")]
-        public void TestPriorityLevelProperty()
-        {
-            CreateDefaultProcess();
-            ProcessThread thread = _process.Threads[0];
-
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
-            {
-                Assert.Throws<PlatformNotSupportedException>(() => thread.PriorityLevel);
-                Assert.Throws<PlatformNotSupportedException>(() => thread.PriorityLevel = ThreadPriorityLevel.AboveNormal);
-                return;
-            }
-
-            ThreadPriorityLevel originalPriority = thread.PriorityLevel;
-
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
-            {
-                Assert.Throws<PlatformNotSupportedException>(() => thread.PriorityLevel = ThreadPriorityLevel.AboveNormal);
-                return;
-            }
-
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")))
-            {
-                Assert.Throws<PlatformNotSupportedException>(() => thread.PriorityLevel = ThreadPriorityLevel.AboveNormal);
-                return;
-            }
-
-            try
-            {
-                thread.PriorityLevel = ThreadPriorityLevel.AboveNormal;
-                Assert.Equal(ThreadPriorityLevel.AboveNormal, thread.PriorityLevel);
-            }
-            finally
-            {
-                thread.PriorityLevel = originalPriority;
-                Assert.Equal(originalPriority, thread.PriorityLevel);
-            }
-        }
-
-        [Fact]
-        [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "Retrieving information about local processes is not supported on uap")]
         public void TestThreadStateProperty()
         {
             CreateDefaultProcess();
index c3c4e27..3b44ab5 100644 (file)
@@ -31,8 +31,6 @@
     <Compile Condition="'$(TargetGroup)' != 'uap'" Include="ProcessTestBase.NonUap.cs" />
     <Compile Condition="'$(TargetGroup)' == 'uap'" Include="ProcessTestBase.Uap.cs" />
     <Compile Include="ProcessTests.cs" />
-    <Compile Include="ProcessTests.Unix.cs" Condition="'$(TargetsWindows)' != 'true'" />
-    <Compile Include="ProcessTests.Windows.cs" Condition="'$(TargetsWindows)' == 'true'" />
     <Compile Include="ProcessThreadTests.cs" />
     <Compile Include="ProcessWaitingTests.cs" />
     <Compile Include="RemotelyInvokable.cs" />
   </ItemGroup>
   <!-- WINDOWS: Shared CoreCLR and .NET Native -->
   <ItemGroup Condition="'$(TargetsWindows)' == 'true'">
+    <Compile Include="ProcessTests.Windows.cs" />
+    <Compile Include="ProcessThreadTests.Windows.cs" />
     <Compile Include="$(CommonPath)\CoreLib\System\PasteArguments.Windows.cs">
       <Link>Common\CoreLib\System\PasteArguments.Windows.cs</Link>
     </Compile>
   </ItemGroup>
   <!-- UNIX -->
   <ItemGroup Condition=" '$(TargetsUnix)' == 'true' ">
+    <Compile Include="ProcessTests.Unix.cs" />
+    <Compile Include="ProcessThreadTests.Unix.cs" />
     <Compile Include="$(CommonPath)\CoreLib\System\PasteArguments.Unix.cs">
       <Link>Common\CoreLib\System\PasteArguments.Unix.cs</Link>
     </Compile>