Add a few more Environment.Exit* tests
authorStephen Toub <stoub@microsoft.com>
Mon, 11 Jul 2016 20:59:47 +0000 (16:59 -0400)
committerStephen Toub <stoub@microsoft.com>
Mon, 11 Jul 2016 20:59:47 +0000 (16:59 -0400)
- Verifies that Environment.Exit(exitCode) passes the code through
- Verifies that Environment.ExitCode passes the code through even after Main exits, e.g. from a foreground thread

Both of these currently fail due to a coreclr issue.

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

src/libraries/System.Runtime.Extensions/tests/System/Environment.Exit.cs
src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs
src/libraries/System.Runtime.Extensions/tests/VoidMainWithExitCodeApp/VoidMainWithExitCodeApp.cs
src/libraries/System.Runtime.Extensions/tests/VoidMainWithExitCodeApp/project.json
src/libraries/System.Runtime.Extensions/tests/project.json

index bed05d8..a069767 100644 (file)
@@ -51,20 +51,24 @@ namespace System.Tests
 
         [ActiveIssue("https://github.com/dotnet/coreclr/issues/6206")]
         [Theory]
-        [MemberData(nameof(ExitCodeValues))]
-        public static void ExitCode_VoidMainAppReturnsSetValue(int expectedExitCode)
+        [InlineData(1)] // setting ExitCode and exiting Main
+        [InlineData(2)] // setting ExitCode both from Main and from an Unloading event handler.
+        [InlineData(3)] // using Exit(exitCode)
+        public static void ExitCode_VoidMainAppReturnsSetValue(int mode)
         {
+            int expectedExitCode = 123;
+
             const string AppName = "VoidMainWithExitCodeApp.exe";
             var psi = new ProcessStartInfo();
             if (File.Exists(HostRunner))
             {
                 psi.FileName = HostRunner;
-                psi.Arguments = AppName + " " + expectedExitCode.ToString();
+                psi.Arguments = $"{AppName} {expectedExitCode} {mode}";
             }
             else
             {
                 psi.FileName = AppName;
-                psi.Arguments = expectedExitCode.ToString();
+                psi.Arguments = $"{expectedExitCode} {mode}";
             }
 
             using (Process p = Process.Start(psi))
index 21dbc0e..9c724cc 100644 (file)
@@ -11,6 +11,7 @@ using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading.Tasks;
 using Xunit;
+using Xunit.NetCore.Extensions;
 
 namespace System.Tests
 {
@@ -178,6 +179,8 @@ namespace System.Tests
             Assert.True(Environment.WorkingSet > 0, "Expected positive WorkingSet value");
         }
 
+        [Trait(XunitConstants.Category, XunitConstants.IgnoreForCI)] // fail fast crashes the process
+        [OuterLoop]
         [Fact]
         public void FailFast_ExpectFailureExitCode()
         {
index 6f16db5..c0d4a07 100644 (file)
@@ -4,6 +4,7 @@
 
 using System;
 using System.Reflection;
+using System.Threading;
 
 namespace VoidMainWithExitCodeApp
 {
@@ -11,9 +12,31 @@ namespace VoidMainWithExitCodeApp
     {
         static void Main(string[] args)
         {
-            int exitCode = args.Length > 0 ? int.Parse(args[0]) : 0;
-            typeof(Environment).GetTypeInfo().GetDeclaredProperty("ExitCode").SetValue(null, exitCode);
-            // Environment.ExitCode = exitCode; // TODO: Remove reflection when package updated with latest Environment exposing ExitCode
+            int exitCode = int.Parse(args[0]);
+            int mode = int.Parse(args[1]);
+
+            PropertyInfo set_ExitCode = typeof(Environment).GetTypeInfo().GetDeclaredProperty("ExitCode");
+            MethodInfo Exit = typeof(Environment).GetTypeInfo().GetDeclaredMethod("Exit");
+
+            switch (mode)
+            {
+                case 1: // set ExitCode and exit
+                    set_ExitCode.SetValue(null, exitCode); // TODO: Environment.ExitCode = exitCode;
+                    break;
+
+                case 2: // set ExitCode, exit, and then set ExitCode from another foreground thread
+                    new Thread(() => // foreground thread
+                    {
+                        Thread.Sleep(1000); // time for Main to exit
+                        set_ExitCode.SetValue(null, exitCode); // TODO: Environment.ExitCode = exitCode;
+                    }).Start();
+                    set_ExitCode.SetValue(null, exitCode - 1); // TODO: Environment.ExitCode = exitCode - 1;
+                    break;
+
+                case 3: // call Environment.Exit(exitCode)
+                    Exit.Invoke(null, new object[] { exitCode }); // TODO: Environment.Exit(exitCode);
+                    break;
+            }
         }
     }
 }
index 7809de3..e24927f 100644 (file)
@@ -3,7 +3,8 @@
     "Microsoft.NETCore.Platforms": "1.0.2-beta-24222-03",
     "System.Runtime": "4.1.1-beta-24222-03",
     "System.Runtime.Extensions": "4.1.1-beta-24222-03",
-    "System.Reflection": "4.1.1-beta-24222-03"
+    "System.Reflection": "4.1.1-beta-24222-03",
+    "System.Threading.Thread": "4.0.1-beta-24222-03"
   },
   "frameworks": {
     "netstandard1.3": {}
index d54a783..fe93441 100644 (file)
@@ -12,6 +12,7 @@
     "System.Runtime.InteropServices.RuntimeInformation": "4.0.1-beta-24222-03",
     "System.Text.RegularExpressions": "4.2.0-beta-24222-03",
     "System.Threading": "4.0.12-beta-24222-03",
+    "System.Threading.Thread": "4.0.1-beta-24222-03",
     "System.Threading.Tasks": "4.0.12-beta-24222-03",
     "test-runtime": {
       "target": "project",