Merge pull request #2820 from kumpera/license-change-rebased
[mono.git] / mono / tests / test-runner.cs
index 065e68b78bd034b550ff5bca37f9ec4e99068f4e..ae52220e335db404bdfe5ff59d2c6d0aa701d702 100644 (file)
@@ -6,24 +6,7 @@
 //
 // Copyright (C) 2008 Novell, Inc (http://www.novell.com)
 //
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 //
 using System;
 using System.IO;
@@ -33,6 +16,7 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.Xml;
 using System.Text.RegularExpressions;
+using Mono.Unix.Native;
 
 //
 // This is a simple test runner with support for parallel execution
@@ -40,6 +24,9 @@ using System.Text.RegularExpressions;
 
 public class TestRunner
 {
+       const string TEST_TIME_FORMAT = "mm\\:ss\\.fff";
+       const string ENV_TIMEOUT = "TEST_DRIVER_TIMEOUT_SEC";
+
        class ProcessData {
                public string test;
                public StreamWriter stdout, stderr;
@@ -58,8 +45,6 @@ public class TestRunner
                string testsuiteName = null;
                string inputFile = null;
 
-               DateTime test_start_time = DateTime.UtcNow;
-
                // FIXME: Add support for runtime arguments + env variables
 
                string disabled_tests = null;
@@ -168,8 +153,7 @@ public class TestRunner
 
                object monitor = new object ();
 
-               if (concurrency != 1)
-                       Console.WriteLine ("Running tests: ");
+               Console.WriteLine ("Running tests: ");
 
                var test_info = new Queue<TestInfo> ();
                if (opt_sets.Count == 0) {
@@ -180,10 +164,19 @@ public class TestRunner
                                foreach (string s in tests)
                                        test_info.Enqueue (new TestInfo { test = s, opt_set = opt });
                        }
-               }               
+               }
+
+               /* compute the max length of test names, to have an optimal output width */
+               int output_width = -1;
+               foreach (TestInfo ti in test_info) {
+                       if (ti.test.Length > output_width)
+                               output_width = Math.Min (120, ti.test.Length);
+               }
 
                List<Thread> threads = new List<Thread> (concurrency);
 
+               DateTime test_start_time = DateTime.UtcNow;
+
                for (int j = 0; j < concurrency; ++j) {
                        Thread thread = new Thread (() => {
                                while (true) {
@@ -195,11 +188,12 @@ public class TestRunner
                                                ti = test_info.Dequeue ();
                                        }
 
+                                       var output = new StringWriter ();
+
                                        string test = ti.test;
                                        string opt_set = ti.opt_set;
 
-                                       if (concurrency == 1)
-                                               Console.Write ("Testing " + test + "... ");
+                                       output.Write (String.Format ("{{0,-{0}}} ", output_width), test);
 
                                        /* Spawn a new process */
                                        string process_args;
@@ -211,6 +205,7 @@ public class TestRunner
                                        info.UseShellExecute = false;
                                        info.RedirectStandardOutput = true;
                                        info.RedirectStandardError = true;
+                                       info.EnvironmentVariables[ENV_TIMEOUT] = timeout.ToString();
                                        Process p = new Process ();
                                        p.StartInfo = info;
 
@@ -245,6 +240,8 @@ public class TestRunner
                                                }
                                        };
 
+                                       var start = DateTime.UtcNow;
+
                                        p.Start ();
 
                                        p.BeginOutputReadLine ();
@@ -255,33 +252,39 @@ public class TestRunner
                                                        timedout.Add (data);
                                                }
 
-                                               if (concurrency == 1)
-                                                       Console.WriteLine ("timed out.");
-                                               else
-                                                       Console.Write (".");
+                                               // Force the process to print a thread dump
+                                               try {
+                                                       Syscall.kill (p.Id, Signum.SIGQUIT);
+                                                       Thread.Sleep (1000);
+                                               } catch {
+                                               }
+
+                                               output.Write ("timed out");
 
                                                p.Kill ();
                                        } else if (p.ExitCode != expectedExitCode) {
+                                               var end = DateTime.UtcNow;
+
                                                lock (monitor) {
                                                        failed.Add (data);
                                                }
 
-                                               if (concurrency == 1)
-                                                       Console.WriteLine ("failed.");
-                                               else
-                                                       Console.Write (".");
+                                               output.Write ("failed, time: {0}, exit code: {1}", (end - start).ToString (TEST_TIME_FORMAT), p.ExitCode);
                                        } else {
+                                               var end = DateTime.UtcNow;
+
                                                lock (monitor) {
                                                        passed.Add (data);
                                                }
 
-                                               if (concurrency == 1)
-                                                       Console.WriteLine ("passed.");
-                                               else
-                                                       Console.Write (".");
+                                               output.Write ("passed, time: {0}", (end - start).ToString (TEST_TIME_FORMAT));
                                        }
 
                                        p.Close ();
+
+                                       lock (monitor) {
+                                               Console.WriteLine (output.ToString ());
+                                       }
                                }
                        });
 
@@ -293,15 +296,16 @@ public class TestRunner
                for (int j = 0; j < threads.Count; ++j)
                        threads [j].Join ();
 
+               TimeSpan test_time = DateTime.UtcNow - test_start_time;
+
                int npassed = passed.Count;
                int nfailed = failed.Count;
                int ntimedout = timedout.Count;
 
-               TimeSpan test_time = DateTime.UtcNow - test_start_time;
                XmlWriterSettings xmlWriterSettings = new XmlWriterSettings ();
                xmlWriterSettings.NewLineOnAttributes = true;
                xmlWriterSettings.Indent = true;
-               using (XmlWriter writer = XmlWriter.Create (String.Format ("TestResults_{0}.xml", testsuiteName), xmlWriterSettings)) {
+               using (XmlWriter writer = XmlWriter.Create (String.Format ("TestResult-{0}.xml", testsuiteName), xmlWriterSettings)) {
                        // <?xml version="1.0" encoding="utf-8" standalone="no"?>
                        writer.WriteStartDocument ();
                        // <!--This file represents the results of running a test suite-->
@@ -420,6 +424,8 @@ public class TestRunner
                        writer.WriteEndDocument ();
                }
 
+               Console.WriteLine ();
+               Console.WriteLine ("Time: {0}", test_time.ToString (TEST_TIME_FORMAT));
                Console.WriteLine ();
                Console.WriteLine ("{0,4} test(s) passed", npassed);
                Console.WriteLine ("{0,4} test(s) failed", nfailed);